깊이에 상관없이 XDocument에서 이름별 요소 조회
는 을 .XDocument◦. 사용하여 특정 .LINQ를 사용하여 특정 이름을 가진 요소에 대해 깊이에 상관없이 조회하고자 합니다.
를 Descendants("element_name")는 현재 자식인 , 는 의 인 인 만 만 인 는 인 .XPath에서 "/element_name"에 해당하는 것을 찾고 있습니다.그냥 사용할까요?XPath 방법을 할 수 있는 ① LINQ ② ③ ④ ⑤ LINQ 방법을 이용해서 할 수 있습니까?
후손들은 절대적으로 일을 잘 해야 합니다.예는 다음과 같습니다.
using System;
using System.Xml.Linq;
class Test
{
static void Main()
{
string xml = @"
<root>
<child id='1'/>
<child id='2'>
<grandchild id='3' />
<grandchild id='4' />
</child>
</root>";
XDocument doc = XDocument.Parse(xml);
foreach (XElement element in doc.Descendants("grandchild"))
{
Console.WriteLine(element);
}
}
}
결과:
<grandchild id="3" />
<grandchild id="4" />
네임스페이스를 나타내는 예:
String TheDocumentContent =
@"
<TheNamespace:root xmlns:TheNamespace = 'http://www.w3.org/2001/XMLSchema' >
<TheNamespace:GrandParent>
<TheNamespace:Parent>
<TheNamespace:Child theName = 'Fred' />
<TheNamespace:Child theName = 'Gabi' />
<TheNamespace:Child theName = 'George'/>
<TheNamespace:Child theName = 'Grace' />
<TheNamespace:Child theName = 'Sam' />
</TheNamespace:Parent>
</TheNamespace:GrandParent>
</TheNamespace:root>
";
XDocument TheDocument = XDocument.Parse( TheDocumentContent );
//Example 1:
var TheElements1 =
from
AnyElement
in
TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
select
AnyElement;
ResultsTxt.AppendText( TheElements1.Count().ToString() );
//Example 2:
var TheElements2 =
from
AnyElement
in
TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
where
AnyElement.Attribute( "theName" ).Value.StartsWith( "G" )
select
AnyElement;
foreach ( XElement CurrentElement in TheElements2 )
{
ResultsTxt.AppendText( "\r\n" + CurrentElement.Attribute( "theName" ).Value );
}
이렇게 할 수 있습니다.
xml.Descendants().Where(p => p.Name.LocalName == "Name of the node to find")
xml는 ㅇXDocument.
이 건물은 다음과 같이Name다음을 가진 객체를 반환합니다.LocalName그리고.Namespace. 그래서 당신이 사용할 수 밖에 없는 것입니다.Name.LocalName이름으로 비교하고 싶다면요.
하위 항목은 필요한 작업을 정확히 수행하지만 요소 이름과 함께 네임스페이스 이름을 포함해야 합니다.생략하면 빈 목록이 나올 것입니다.
이를 달성하는 데는 두 가지 방법이 있습니다.
- LINQ에서 XML로
- XPath
다음은 이러한 접근법을 사용한 샘플입니다.
List<XElement> result = doc.Root.Element("emails").Elements("emailAddress").ToList();
XPath를 사용하는 경우 IE numberable로 다음과 같은 조작을 수행해야 합니다.
IEnumerable<XElement> mails = ((IEnumerable)doc.XPathEvaluate("/emails/emailAddress")).Cast<XElement>();
참고:
var res = doc.XPathEvaluate("/emails/emailAddress");
결과가 Null 포인터이거나 결과가 없습니다.
사용중입니다XPathSelectElements로는장법법은과 같은 방식으로 작동하는 확장 XmlDocument.SelectNodes방법:
using System;
using System.Xml.Linq;
using System.Xml.XPath; // for XPathSelectElements
namespace testconsoleApp
{
class Program
{
static void Main(string[] args)
{
XDocument xdoc = XDocument.Parse(
@"<root>
<child>
<name>john</name>
</child>
<child>
<name>fred</name>
</child>
<child>
<name>mark</name>
</child>
</root>");
foreach (var childElem in xdoc.XPathSelectElements("//child"))
{
string childName = childElem.Element("name").Value;
Console.WriteLine(childName);
}
}
}
}
@Francisco Goldenstein 답변에 따라 확장 방법을 작성했습니다.
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Mediatel.Framework
{
public static class XDocumentHelper
{
public static IEnumerable<XElement> DescendantElements(this XDocument xDocument, string nodeName)
{
return xDocument.Descendants().Where(p => p.Name.LocalName == nodeName);
}
}
}
이것은 LINQ에 기반한 솔루션의 나의 변형과 의 Descendants method입니다.XDocument급
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
XDocument xml = XDocument.Parse(@"
<root>
<child id='1'/>
<child id='2'>
<subChild id='3'>
<extChild id='5' />
<extChild id='6' />
</subChild>
<subChild id='4'>
<extChild id='7' />
</subChild>
</child>
</root>");
xml.Descendants().Where(p => p.Name.LocalName == "extChild")
.ToList()
.ForEach(e => Console.WriteLine(e));
Console.ReadLine();
}
}
우리는 위의 내용이 사실이라는 것을 알고 있습니다.존은 결코 틀리지 않습니다. 실생활의 소망은 조금 더 멀리 갈 수 있습니다.
<ota:OTA_AirAvailRQ
xmlns:ota="http://www.opentravel.org/OTA/2003/05" EchoToken="740" Target=" Test" TimeStamp="2012-07-19T14:42:55.198Z" Version="1.1">
<ota:OriginDestinationInformation>
<ota:DepartureDateTime>2012-07-20T00:00:00Z</ota:DepartureDateTime>
</ota:OriginDestinationInformation>
</ota:OTA_AirAvailRQ>
예를 들어, 보통 문제는 위의 XML 문서에서 EchoToken을 어떻게 얻을 수 있을까 하는 것입니다.또는 이름 속성으로 요소를 흐리게 하는 방법.
아래와 같은 네임스페이스와 이름으로 액세스하면 찾을 수 있습니다.
doc.Descendants().Where(p => p.Name.LocalName == "OTA_AirAvailRQ").Attributes("EchoToken").FirstOrDefault().Value이것처럼 속성 내용 값으로 찾을 수 있습니다.
(Code and Instructions는 C#용이며 다른 언어의 경우 약간 변경해야 할 수 있습니다.)
이 예제는 자식이 많은 상위 노드에서 읽으려면 완벽하게 작동합니다. 예를 들어 다음 XML을 보십시오.
<?xml version="1.0" encoding="UTF-8"?>
<emails>
<emailAddress>jdoe@set.ca</emailAddress>
<emailAddress>jsmith@hit.ca</emailAddress>
<emailAddress>rgreen@set_ig.ca</emailAddress>
</emails>
이제 아래 코드를 사용하여(XML 파일이 리소스에 저장되어 있음을 명심하십시오(리소스에 대한 도움말은 스니펫 끝에 있는 링크 참조) "이메일" 태그 내에서 각 이메일 주소를 얻을 수 있습니다.
XDocument doc = XDocument.Parse(Properties.Resources.EmailAddresses);
var emailAddresses = (from emails in doc.Descendants("emailAddress")
select emails.Value);
foreach (var email in emailAddresses)
{
//Comment out if using WPF or Windows Form project
Console.WriteLine(email.ToString());
//Remove comment if using WPF or Windows Form project
//MessageBox.Show(email.ToString());
}
결과.
- jdoe@set.ca
- jsmith@hit.ca
- rgreen@set_ig.ca
참고: 콘솔 응용 프로그램과 WPF 또는 Windows Forms의 경우 "시스템 사용"을 추가해야 합니다.Xml.Linq;" 프로젝트 맨 위에 지시문을 사용하면 콘솔의 경우 Using 지시문을 추가하기 전에 이 네임스페이스에 대한 참조를 추가해야 합니다.또한 콘솔의 경우 "속성 폴더" 아래에 기본적으로 리소스 파일이 없으므로 수동으로 리소스 파일을 추가해야 합니다.아래 MSDN 기사는 이에 대해 자세히 설명합니다.
언급URL : https://stackoverflow.com/questions/566167/query-an-xdocument-for-elements-by-name-at-any-depth
'codememo' 카테고리의 다른 글
| MySQL 선택에서 업데이트 (0) | 2023.09.10 |
|---|---|
| iframe의 내용에 대해 본문 스타일 재정의 (0) | 2023.09.10 |
| 명령줄에서 (스크립트가 아닌) PowerShell을 시작하는 방법 (0) | 2023.09.10 |
| 퍼블릭 도메인 라이센스가 있는 최상의 zip 라이브러리 (0) | 2023.09.10 |
| 도커-컴포지트 빌드와 도커-빌트의 차이점은 무엇입니까? (0) | 2023.09.10 |