Was ist ein guter Weg, um einen bestimmten Wert in einem XML-Dokument mit C # zu finden?

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

  •  22-08-2019
  •  | 
  •  

Frage

Ich rufe einen WebService von Oracle ausgesetzt, die eine Eingabe eines ItemID und kehrt zu mir die entsprechende Artikelnummer akzeptiert. Ich möchte die Artikelnummer ergreifen, die in der Antwort.

enthalten sind aus der XML zurückgegeben wurde

Die XML sieht wie folgt aus:

<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>

Ich bin interessiert nur den <ns0:result>1010603</ns0:result> in Grabbing vor allem nur die 1.010.603.

Ich habe nicht viel Arbeit Parsen von XML mit C # getan, und ich bin das Spiel mit ein paar verschiedene Methoden so weit. Was ist der empfohlene Weg, dies zu tun?

Ich bin auf VS2008 (so ist XPath verfügbar usw.)

War es hilfreich?

Lösung

Ich würde persönlich LINQ to XML verwenden, weil ich die einfacher finden als mit XPath zu behandeln, vor allem, wenn Namespaces beteiligt ist. Sie würden so etwas wie:

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

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

Beachten Sie, dass hier doc wird erwartet, dass ein XDocument sein, nicht ein XmlDocument . (Meine Vermutung ist, dass es sich dabei, warum es nicht für Sie auftauchen.)

Andere Tipps

FWIW können Sie das Namespace-Problem mit einer XPath-ähnlichen betrügen: //*[local-name()='result']

Wenn Sie nicht wollen, für Linq gehen Sie XPathDocument verwenden könnte den Wert abzurufen:

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 hat einen niedrigeren Speicherbedarf und ist wahrscheinlich schneller in Ihrem Szenario als XmlDocument. XmlDocument baut ein vollständiges Objektmodell Ihres XML-Dokuments im Speicher während XPathDocument up macht das nicht.

Aus der Spitze von meinem Kopf, sollte folgende Arbeiten:

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

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

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

Der Namespace-Code sieht wie folgt aus:

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

Sie müssen den Namespace-Manager verwenden, da das XML-Dokument mit Namespaces hat zugeordnet ist, und XPath verwendet diese Abfrage Auflösung.

Um dies zu lösen, habe ich Jon Skeet Antwort. Hier ist der Code, den ich hatte zu implementieren diese Arbeit zu machen (für jemand anderen zukünftigen Nutzen).

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;

Dies setzt natürlich voraus, ich bin immer meine Antwort zurück von einer HttpWebRequest namens Anfrage .

Es gibt sehr gute und vollständige Antworten auf diese Frage.

Ich würde hinzufügen nur aus Neugier, dass ein extrem einfacher XPath-Ausdruck macht den Job in diesem speziellen Fall:

normalize-space(/)

Dies ist leicht in C # getan etwas wie die beiden Linien mit unter:

        XPathNavigator navigator = document.CreateNavigator();

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

Mit der guten Optimierung des .NET XPath Engine, seine Bewertung auch effizient sein kann.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top