我有一个XML文档,如下所示:
<kmsg xmlns="http://url1" xmlns:env="url1" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xsi:schemaLocation="http://location that does not exist.xsd">
<header>
<env:envelope>
<env:source branch="907" machine="0" password="J123"/>
</env:envelope>
</header>
<body>
<OrderResponse xmlns="urn:schemasbasdaorg:2000:orderResponse:xdr:3.01">
<SomeMoreNodes/>
</OrderResponse>
</body>
尽管指定了命名空间,但它没有任何可用的模式(我从外部源获取这些,因此无法控制)。我正在使用XDocument解析它,但不会为不在env命名空间中的项获取空值。我正在设置这样的XDocument:
XDocument Source = XDocument.Load("Testfile.xml");
XmlNamespaceManager oManager = new XmlNamespaceManager(new NameTable());
oManager.AddNamespace(String.Empty, "http://xml.kerridge.net/k8msg");
oManager.AddNamespace("env", "http://xml.kerridge.net/k8msgEnvelope");
然后我尝试获取值:
?Source.XPathSelectElement(“// kmsg”,oManager)
空
?Source.XPathSelectElement(“// header”,oManager)
空
?Source.XPathSelectElement(“// env:source”,oManager)
正确获取节点
我认为这与我设置命名空间管理器错误有关,但我无法弄清楚如何修复它。任何帮助都会很棒。
由于
答案 0 :(得分:19)
除了@Mads-Hansen的正确评论之外,您还有一个典型的问题,即没有为其中一个名称空间定义(非空)前缀。
记住:XPath认为任何未加前缀的名称都在“无名称空间”中。
因此这是错误的:
Source.XPathSelectElement("//kmsg", oManager)
此XPath表达式要选择“无命名空间”中的所有kmsg
元素,并且它正确选择任何内容,因为提供的XML文档中的任何kmsg
元素都在"http://url1"
中命名空间,而不是“无命名空间”。
要正确执行:
oManager.AddNamespace("xxx", "http://url1");
Source.XPathSelectElement("//xxx:kmsg", oManager)
答案 1 :(得分:1)
源XML中声明的namespace-URI与您在XmlNamespaceManager
注册的namespace-URI不匹配。
在源XML中:
http://url1
url1
在您声明的XmlNamespaceManager
中:
http://xml.kerridge.net/k8msg
http://xml.kerridge.net/k8msgEnvelope
namespace-uri值必须匹配,否则你选择不同的元素名称,永远不会匹配。