récupérer - xml et c#




Quel est un bon moyen de trouver une valeur spécifique dans un document XML en utilisant C#? (4)

J'appelle un WebService exposé par Oracle qui accepte une entrée d'un ItemID et me renvoie le numéro d'article correspondant. Je veux saisir le numéro d'article qui a été renvoyé à partir du code XML contenu dans la réponse.

Le XML ressemble à ceci:

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

Je suis intéressé à saisir uniquement le <ns0:result>1010603</ns0:result> particulier seulement le 1010603.

Je n'ai pas fait beaucoup de travail d'analyse XML en utilisant C # et je joue avec quelques méthodes différentes jusqu'à présent. Quelle est la manière recommandée de faire ceci?

Je suis sur VS2008 (donc XPath est disponible, etc.)


Du haut de ma tête, ce qui suit devrait fonctionner:

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

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

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

Le code de l'espace de nommage ressemble à ceci:

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

Vous devez utiliser le gestionnaire d'espaces de noms car le document XML est associé à des espaces de noms et XPath l'utilise dans la résolution de la requête.


Il y a de très bonnes et complètes réponses à cette question.

J'ajouterai juste par curiosité, qu'une expression XPath extrêmement simple fait le travail dans ce cas particulier:

normalize-space(/)

Ceci est facilement fait en C # en utilisant quelque chose comme les deux lignes ci-dessous:

        XPathNavigator navigator = document.CreateNavigator();

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

Avec la bonne optimisation du moteur .NET XPath, son évaluation peut même être efficace.


Pour résoudre ce problème, j'ai utilisé la réponse de Jon Skeet. Voici le code que j'ai dû mettre en œuvre pour que cela fonctionne (pour le bénéfice futur de quelqu'un d'autre).

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;

Cela suppose évidemment que je reçois ma réponse d'une demande nommée HttpWebRequest.


Si vous ne voulez pas utiliser Linq, vous pouvez utiliser XPathDocument pour récupérer la valeur:

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 a une empreinte mémoire inférieure et est probablement plus rapide dans votre scénario que XmlDocument. XmlDocument crée un modèle objet complet de votre document XML en mémoire alors que XPathDocument ne le fait pas.







searching-xml