什么是找到使用C#的XML文档中的特定值的好办法?
-
22-08-2019 - |
题
我打电话由Oracle暴露一个WebService接受和项ID的输入返回到我的相应项目编号。我想抓住已经返回了包含在响应中的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是可用等)
解决方案
我个人使用LINQ到XML,因为我发现更容易处理比XPath的,尤其是当命名空间都参与其中。你会做这样的事情:
XNamespace ns0 = "http://dev1/MyWebService1.wsdl";
String result = doc.Descendants(ns0 + "result").First().Value;
请注意,这里doc
预期为一个 XDocument
, 不的一个 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的建立在内存中,而XPathDocument的XML文档的一个完整的对象模型没有做到这一点。
我的头顶部,下面应该工作:
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使用该查询分辨率。
要解决这个问题,我用乔恩斯基特的答案。下面是我不得不实施,使这项工作(对别人的未来利益)的代码。
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引擎的良好优化,其评价甚至可能是有效的。