C#을 사용하여 XML 문서에서 특정 값을 찾는 좋은 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/374734

  •  22-08-2019
  •  | 
  •  

문제

나는 itemid의 입력을 받아들이고 해당 항목 번호를 반환하는 Oracle에 의해 노출 된 웹 서비스를 호출합니다. 응답에 포함 된 XML에서 반환 된 품목 번호를 가져오고 싶습니다.

XML은 다음과 같습니다.

<env:Envelope
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns0="http://dev1/MyWebService1.wsdl">
 <env:Header>
  <wsse:Security
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    env:mustUnderstand="1"/>
 </env:Header>
 <env:Body>
  <ns0:getItemNbrByItemIdResponseElement>
   <ns0:result>1010603</ns0:result>
  </ns0:getItemNbrByItemIdResponseElement>
 </env:Body>
</env:Envelope>

나는 만 잡는 데 관심이 있습니다 <ns0:result>1010603</ns0:result> 특히 1010603 만.

C#을 사용하여 XML을 구문 분석하는 작업을 많이하지 않았으며 지금까지 몇 가지 다른 방법으로 놀고 있습니다. 권장하는 방법은 무엇입니까?

나는 VS2008에 있습니다 (XPath가 가능합니다.)

도움이 되었습니까?

해결책

특히 네임 스페이스가 관련 될 때 XPath보다 처리하기가 더 쉽기 때문에 개인적으로 LINQ에서 XML을 사용합니다. 당신은 다음과 같은 일을 할 것입니다.

XNamespace ns0 = "http://dev1/MyWebService1.wsdl";

String result = doc.Descendants(ns0 + "result").First().Value;

주목하십시오 doc 다음은 다음과 같습니다 XDocument, ~ 아니다 an XmlDocument. (내 생각에 이것이 당신을 위해 나타나지 않은 이유입니다.)

다른 팁

fwiw 당신은 다음과 같은 xpath로 네임 스페이스 문제를 속일 수 있습니다. //*[local-name()='result']

LINQ를 원하지 않으면 XPathDocument를 사용하여 값을 검색 할 수 있습니다.

XPathDocument xmldoc = new XPathDocument(@"C:\tmp\sample.xml");
XPathNavigator nav = xmldoc.CreateNavigator();

XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
nsMgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl");

XPathNavigator result = nav.SelectSingleNode("//ns0:result", nsMgr);
System.Diagnostics.Debug.WriteLine(result.Value);

XPathDocument는 메모리 발자국이 낮으며 XMLDocument보다 시나리오에서 더 빠릅니다. XMLDocument는 메모리에서 XML 문서의 완전한 객체 모델을 구축하는 반면 XPathDocument는 그렇게하지 않습니다.

내 머리 꼭대기에서 다음이 작동해야합니다.

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;

XmlNamespaceManager mgr = GetNamespace(doc);
doc.LoadXml(xmltext);

XmlNode nd = doc.DocumentElement.SelectSingleNode("//ns0:result", mgr);

네임 스페이스 코드는 다음과 같습니다.

private XmlNamespaceManager GetNamespace(XmlDocument document)
{
    XmlNamespaceManager mgr = new XmlNamespaceManager(document.NameTable);
    mgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl");
    return mgr;
}

XML 문서에는 네임 스페이스와 관련된 네임 스페이스가 있고 XPath는 쿼리 해상도에서이를 사용하므로 네임 스페이스 관리자를 사용해야합니다.

이것을 해결하기 위해 Jon Skeet의 대답을 사용했습니다. 이 작업을 수행하기 위해 구현해야 할 코드는 다음과 같습니다 (다른 사람의 미래 이익을 위해).

XmlDocument xmlDoc = new XmlDocument();

XNamespace ns0 = "http://dev1/MyWebService1.wsdl";

xmlDoc.Load(request.GetResponse().GetResponseStream());

XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc));                          

String result = xDoc.Descendants(ns0 + "result").First().Value;

물론 이것은 내가 명명 된 httpwebrequest에서 내 응답을 받고 있다고 가정합니다. 요구.

이 질문에 대한 매우 훌륭하고 완전한 답변이 있습니다.

나는 추가 할 것이다 호기심에서 매우 간단한 xpath 표현이 작업을 수행한다는 이 특별한 경우 :

    normalize-space(/)

이것은 아래의 두 줄과 같은 것을 사용하여 C#에서 쉽게 수행됩니다.

        XPathNavigator navigator = document.CreateNavigator();

        string res = (string)navigator.Evaluate("normalize-space(/)");

.NET XPath 엔진의 최적화로 평가가 효율적 일 수도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top