使用XDocument、XPath和命名空间出现了奇怪的问题

16

我有一个长这样的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 命名空间的项目中仍然得到 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

我猜这与我错误设置命名空间管理器有关,但我无法弄清如何修复它。 感谢任何帮助。

谢谢

2个回答

26

除了@Mads-Hansen所说的正确备注之外,您还面临一个典型的问题,即未为其中一个命名空间定义(非空)前缀。

请记住:XPath认为任何未命名的名称都在“无命名空间”中。

因此,下面是错误的

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

这个XPath表达式想选择所有不带命名空间的kmsg元素,它正确地选择了什么都没有,因为提供的XML文档中任何一个kmsg元素都处于"http://url1"的命名空间中,而不是在“无命名空间”中。

要正确执行此操作:

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

1

您源XML中声明的命名空间URI与您在XmlNamespaceManager中注册的命名空间URI不匹配。

在您的源XML中:

  1. 匿名命名空间(无前缀)具有命名空间URI:http://url1
  2. env命名空间前缀具有命名空间URI:url1

在您的XmlNamespaceManager中声明:

  1. 匿名命名空间(无前缀)具有命名空间URI:http://xml.kerridge.net/k8msg
  2. env命名空间前缀具有命名空间URI:http://xml.kerridge.net/k8msgEnvelope

命名空间URI值必须匹配,否则您将选择不同的元素名称,并永远无法匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接