XDocument,XPath和命名空间的奇怪之处

Chr*_*eet 13 c# xpath linq-to-xml xml-namespaces

我有一个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>
Run Code Online (Sandbox Code Playgroud)

尽管指定了名称空间,但它没有任何可用的模式(我从外部源获取此类,因此无法控制).我正在使用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");
Run Code Online (Sandbox Code Playgroud)

然后我尝试获取值:

?Source.XPathSelectElement("// kmsg",oManager)

空值

?Source.XPathSelectElement("// header",oManager)

空值

?Source.XPathSelectElement("// env:source",oManager)

正确获取节点

我假设这与我设置命名空间管理器错误有关,但我无法弄清楚如何解决它.任何帮助都会很棒.

谢谢

Dim*_*hev 22

除了@Mads-Hansen的正确注释之外,您还有一个典型的问题,即没有为其中一个命名空间定义(非空)前缀.

请记住:XPath认为任何未加前缀的名称都在"无名称空间"中.

因此这是错误的:

Source.XPathSelectElement("//kmsg", oManager)
Run Code Online (Sandbox Code Playgroud)

此XPath表达式希望选择kmsg"无命名空间"中的所有元素,并且它正确地选择任何内容,因为kmsg提供的XML文档中的任何元素都在"http://url1"命名空间中,而不是在"无命名空间"中.

要正确地做到:

oManager.AddNamespace("xxx", "http://url1");      
Source.XPathSelectElement("//xxx:kmsg", oManager)
Run Code Online (Sandbox Code Playgroud)