开发者

Weirdness with XDocument, XPath and namespaces

开发者 https://www.devze.com 2023-01-16 09:31 出处:网络
I have an XML document that looks like this: <kmsg xmlns=\"http://url1\" xmlns:env=\"url1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchemainstance\" xsi:schemaLocation=\"http://location that does no

I have an XML document that looks like this:

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

It does not have any schemas available despite having namespaces specified (I'm getting this from an external source so have no control). I'm parsing it with an XDocument, but keep getting nulls for the items not in the env namespace. I'm setting up the XDocument like this:

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");

Then I try to get values:

?Source.XPathSelectElement("//kmsg",开发者_开发技巧 oManager)

null

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

null

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

Gets the node correctly

I'm assuming this is something to do with me setting up the namespace manager wrong but I can't figure out how to fix it. Any help would be great.

Thanks


In addition to the correct remark by @Mads-Hansen, you have the typical problem of not defining a (nonempty) prefix for one of the namespaces.

Remember: XPath considers any unprefixed name to be in "no namespace".

Therefore this is wrong:

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

This XPath expression wants to select all kmsg elements that are in "no namespace" and it correctly selects nothing, because any kmsg elements in the provided XML document are in the "http://url1" namespace, and not in "no namespace".

To do it correctly:

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


The namespace-URI's declared in your source XML do not match the namespace-URI's that you are registering with your XmlNamespaceManager.

In your source XML:

  1. The anonymous namespace (no prefix) has the namespace-uri: http://url1
  2. The env namespace prefix has the namespace-uri: url1

In your XmlNamespaceManager you declared:

  1. The anonymous namespace (no prefix) has the namespace-uri: http://xml.kerridge.net/k8msg
  2. The env namespace prefix has the namespace-uri: http://xml.kerridge.net/k8msgEnvelope

The namespace-uri values have to match, otherwise you are selecting different element names and will never get a match.

0

精彩评论

暂无评论...
验证码 换一张
取 消