XML을 읽을 LINQ
다음 XML 파일을 사용하고 있습니다.
<root>
<level1 name="A">
<level2 name="A1" />
<level2 name="A2" />
</level1>
<level1 name="B">
<level2 name="B1" />
<level2 name="B2" />
</level1>
<level1 name="C" />
</root>
누가 이 결과를 출력하는 가장 간단한 방법인 LINQ를 사용하여 C# 코드를 줄 수 있습니까?
(공간이 a인 경우 추가 공간을 기록합니다.level2마디)
A
A1
A2
B
B1
B2
C
현재 다음 코드를 작성했습니다.
XDocument xdoc = XDocument.Load("data.xml"));
var lv1s = from lv1 in xdoc.Descendants("level1")
select lv1.Attribute("name").Value;
foreach (var lv1 in lv1s)
{
result.AppendLine(lv1);
var lv2s = from lv2 in xdoc...???
}
이거 먹어봐요.
using System.Xml.Linq;
void Main()
{
StringBuilder result = new StringBuilder();
//Load xml
XDocument xdoc = XDocument.Load("data.xml");
//Run query
var lv1s = from lv1 in xdoc.Descendants("level1")
select new {
Header = lv1.Attribute("name").Value,
Children = lv1.Descendants("level2")
};
//Loop through results
foreach (var lv1 in lv1s){
result.AppendLine(lv1.Header);
foreach(var lv2 in lv1.Children)
result.AppendLine(" " + lv2.Attribute("name").Value);
}
Console.WriteLine(result);
}
또는 보다 일반적인 접근 방식(즉, "levelN"까지 네스팅하는 경우)을 원할 경우:
void Main()
{
XElement rootElement = XElement.Load(@"c:\events\test.xml");
Console.WriteLine(GetOutline(0, rootElement));
}
private string GetOutline(int indentLevel, XElement element)
{
StringBuilder result = new StringBuilder();
if (element.Attribute("name") != null)
{
result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value);
}
foreach (XElement childElement in element.Elements())
{
result.Append(GetOutline(indentLevel + 1, childElement));
}
return result.ToString();
}
평범한 늙은이 몇명.foreach루프는 다음과 같은 깨끗한 솔루션을 제공합니다.
foreach (XElement level1Element in XElement.Load("data.xml").Elements("level1"))
{
result.AppendLine(level1Element.Attribute("name").Value);
foreach (XElement level2Element in level1Element.Elements("level2"))
{
result.AppendLine(" " + level2Element.Attribute("name").Value);
}
}
다음은 @bendewey & @dommer 예제를 기반으로 구축된 몇 가지 완전한 작업 예제입니다.작동하려면 각각의 기능을 조금씩 조정해야 했지만, 다른 LINQ 초보자가 작동 사례를 찾고 있는 경우 여기 있습니다.
//bendewey's example using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ1
{
static void Main( )
{
//Load xml
XDocument xdoc = XDocument.Load(@"c:\\data.xml"); //you'll have to edit your path
//Run query
var lv1s = from lv1 in xdoc.Descendants("level1")
select new
{
Header = lv1.Attribute("name").Value,
Children = lv1.Descendants("level2")
};
StringBuilder result = new StringBuilder(); //had to add this to make the result work
//Loop through results
foreach (var lv1 in lv1s)
{
result.AppendLine(" " + lv1.Header);
foreach(var lv2 in lv1.Children)
result.AppendLine(" " + lv2.Attribute("name").Value);
}
Console.WriteLine(result.ToString()); //added this so you could see the output on the console
}
}
다음은.
//Dommer's example, using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ
{
static void Main( )
{
XElement rootElement = XElement.Load(@"c:\\data.xml"); //you'll have to edit your path
Console.WriteLine(GetOutline(0, rootElement));
}
static private string GetOutline(int indentLevel, XElement element)
{
StringBuilder result = new StringBuilder();
if (element.Attribute("name") != null)
{
result = result.AppendLine(new string(' ', indentLevel * 2) + element.Attribute("name").Value);
}
foreach (XElement childElement in element.Elements())
{
result.Append(GetOutline(indentLevel + 1, childElement));
}
return result.ToString();
}
}
이 둘 다 csc.exe 버전 4.0.30319.1을 사용하는 VS2010에서 컴파일 및 작동하며 정확히 동일한 출력을 제공합니다.이것들이 코드의 작동 예를 찾고 있는 다른 사람에게 도움이 되기를 바랍니다.
편집: @eglasius의 예도 제게 유용해졌기 때문에 추가했습니다.
//@eglasius example, still using data.xml from OP
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
class loadXMLToLINQ2
{
static void Main( )
{
StringBuilder result = new StringBuilder(); //needed for result below
XDocument xdoc = XDocument.Load(@"c:\\deg\\data.xml"); //you'll have to edit your path
var lv1s = xdoc.Root.Descendants("level1");
var lvs = lv1s.SelectMany(l=>
new string[]{ l.Attribute("name").Value }
.Union(
l.Descendants("level2")
.Select(l2=>" " + l2.Attribute("name").Value)
)
);
foreach (var lv in lvs)
{
result.AppendLine(lv);
}
Console.WriteLine(result);//added this so you could see the result
}
}
XDocument xdoc = XDocument.Load("data.xml");
var lv1s = xdoc.Root.Descendants("level1");
var lvs = lv1s.SelectMany(l=>
new string[]{ l.Attribute("name").Value }
.Union(
l.Descendants("level2")
.Select(l2=>" " + l2.Attribute("name").Value)
)
);
foreach (var lv in lvs)
{
result.AppendLine(lv);
}
Ps. 이거 써야 돼요.이 버전에서 루트를 찾습니다.
XML 파일을 비동기적으로 로드하면 특히 파일 크기가 크거나 로드하는 데 시간이 오래 걸리는 경우 성능이 향상될 수 있습니다.이 예에서는 다음을 사용합니다.XDocument.LoadAsync파일이 로드되는 동안 응용 프로그램이 응답하지 않는 것을 방지할 수 있는 XML 파일을 비동기적으로 로드하고 구문 분석하는 방법입니다.
데모: https://dotnetfiddle.net/PGFE7c (XML 문자열 구문 분석 사용)
구현:
XDocument doc;
// Open the XML file using File.OpenRead and pass the stream to
// XDocument.LoadAsync to load and parse the XML asynchronously
using (var stream = File.OpenRead("data.xml"))
{
doc = await XDocument.LoadAsync(stream, LoadOptions.None, CancellationToken.None);
}
// Select the level1 elements from the document and create an anonymous object for each element
// with a Name property containing the value of the "name" attribute and a Children property
// containing a collection of the names of the level2 elements
var results = doc.Descendants("level1")
.Select(level1 => new
{
Name = level1.Attribute("name").Value,
Children = level1.Descendants("level2")
.Select(level2 => level2.Attribute("name").Value)
});
foreach (var result in results)
{
Console.WriteLine(result.Name);
foreach (var child in result.Children)
Console.WriteLine(" " + child);
}
결과:
A
A1
A2
B
B1
B2
C
언급URL : https://stackoverflow.com/questions/670563/linq-to-read-xml
'programing' 카테고리의 다른 글
| 워드프레스에서 PHPSESSID 쿠키 도메인 이름을 변경하는 방법은? (0) | 2023.10.31 |
|---|---|
| 비트 조작을 이용하여 64비트 값에서 유일한 세트 비트의 위치를 효율적으로 찾는 방법은? (0) | 2023.10.31 |
| 불규칙한 분리기를 위해 팬더 read_csv의 분리기를 더 유연한 wrt 공백으로 만드는 방법은 무엇입니까? (0) | 2023.10.31 |
| 안드로이드 스튜디오를 다운로드하지 않고 안드로이드 SDK를 다운로드하려면 어떻게 해야 합니까? (0) | 2023.10.31 |
| C++ 예외는 C 코드를 통해 안전하게 전파됩니까? (0) | 2023.10.31 |