What is a good way to find a specific value in an XML document using C#?

百般思念 提交于 2019-12-04 06:26:17

I'd personally use LINQ to XML, because I find that easier to deal with than XPath, particularly when namespaces are involved. You'd do something like:

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

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

Note that doc here is expected to be an XDocument, not an XmlDocument. (My guess is that this is why it wasn't showing up for you.)

fwiw you can cheat the namespace issue with an xpath like this: //*[local-name()='result']

If you don't want to go for Linq you could use XPathDocument to retrieve the value:

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 has a lower memory footprint and is most likely faster in your scenario than XmlDocument. XmlDocument builds up a complete object model of your XML document in memory whereas XPathDocument does not do that.

Off the top of my head, the following should work:

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

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

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

The namespace code looks like this:

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

You need to use the namespace manager because the XML document has namespaces associated with it, and XPath uses this in query resolution.

To solve this, I used Jon Skeet's answer. Here's the code that I had to implement to make this work (for anyone else's future benefit).

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;

This of course assumes I'm getting my response back from an HttpWebRequest named request.

There are very good and complete answers to this question.

I'd add just out of curiosity, that an extremely simple XPath expression does the job in this particular case:

    normalize-space(/)

This is easily done in C# using something like the two lines below:

        XPathNavigator navigator = document.CreateNavigator();

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

With the good optimization of the .NET XPath engine, its evaluation may even be efficient.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!