c# - XDocument、XPath 和命名空间的奇怪之处

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

尽管指定了 namespace ,但它没有任何可用的模式(我是从外部来源获取的,所以无法控制)。我正在使用 XDocument 对其进行解析,但对于不在 env 命名空间中的项目,不断获取 null。我正在像这样设置 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)

null

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

null

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

Gets the node correctly

我假设这与我错误地设置命名空间管理器有关,但我不知道如何修复它。任何帮助都会很棒。

谢谢

最佳答案

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

记住:XPath 认为任何没有前缀的名称都在“无 namespace ”中。

因此这是错误的:

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

此 XPath 表达式想要选择“无命名空间”中的所有 kmsg 元素,但它正确地没有选择任何内容,因为提供的 XML 文档中的任何 kmsg 元素都在"http://url1" 命名空间,而不是在“无命名空间”中。

正确做法:

oManager.AddNamespace("xxx", "http://url1");      
Source.XPathSelectElement("//xxx:kmsg", oManager)

关于c# - XDocument、XPath 和命名空间的奇怪之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3715936/

相关文章:

c# - 错误 :- The XmlReader state should be Interactive on XDocument. 加载

c# - 索引访问 XElement 的子节点

c# - 如何添加/删除动态创建的用户控件

C# hex byte 0x09 (ascii -> tab) to "\t"string

c# - 使用根目录字符串

ruby - 如何在 Nokogiri 中使用带有 XPath 的 xmlns 声明

c# - 什么会导致 MVC4 Controller 只返回状态代码而不返回局部 View ?

php - 相对 xpath php

jquery - 使用xpath获取div中的文本,包括span

c# - 添加新的 XElement 会在保存时将整个 XML 文件附加到现有文件