2010-09-15 11 views
8

Ich habe ein XML-Dokument, das wie folgt aussieht:Weirdness mit XDocument, XPath und Namespaces

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

Es hat keine Schemata trotz verfügbaren Namensräume mit angegeben (ich bin immer dies von einem externe Quelle also keine Kontrolle). Ich analysiere es mit einem XDocument, bekomme aber Nullen für die Elemente, die nicht im env-Namespace sind. Ich gründe die XDocument so zusammen:

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

Dann versuche ich, Werte zu erhalten:

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

null

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

null

? So urce.XPathSelectElement („// env: source“, oManager)

Ruft den Knoten richtig

Ich gehe davon aus das etwas ist, mit mir den Namespace-Manager falsch Einrichtung zu tun, aber ich kann nicht herausfinden wie man es repariert. Jede Hilfe wäre großartig.

Dank

Antwort

15

Neben der korrekten Bemerkung von @ Mads-Hansen haben Sie das typische Problem, für einen der Namespaces kein (nicht leeres) Präfix zu definieren.

Erinnern Sie sich: XPath betrachtet beliebigen Namen ohne Präfix in "kein Namespace".

Daher ist dies falsch:

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

Dieser XPath-Ausdruck will alle kmsg Elemente auszuwählen, die in „kein Namensraum“ sind und wählt richtig nichts, weil alle kmsg Elemente im bereitgestellten XML-Dokument sind im Namespace "http://url1" und nicht in "no namespace".

Um es richtig zu tun:

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

Die in der XML-Quellnamensraum-URI deklariert haben den Namespace-URI nicht überein, dass Sie mit Ihrem XmlNamespaceManager registrieren.

In Ihrer Quelle XML:

  1. Der anonyme Namespace (kein Präfix) hat die Namespace-uri: http://url1
  2. Der env Namespacepräfix hat die Namespace-uri: url1

In Ihrer XmlNamespaceManager haben Sie erklärt:

  1. Der anonyme Namespace (kein Präfix) hat die Namespace-uri: http://xml.kerridge.net/k8msg
  2. Die env Namespacepräfix die Namespace-uri haben: http://xml.kerridge.net/k8msgEnvelope

Die Namespace-uri Werte müssen übereinstimmen, sonst sind Sie Auswahl verschiedener Elementnamen und wird nie eine Übereinstimmung erhalten.