2010-09-15 16 views
8

Ho un documento XML che assomiglia a questo:Stranezze con XDocument, XPath e gli spazi dei nomi

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

non ha alcun schemi disponibili pur avendo spazi dei nomi specificati (sto ricevendo questo da un la fonte esterna non ha quindi alcun controllo). Lo sto analizzando con un XDocument, ma continuo a ottenere valori null per gli elementi non nello spazio dei nomi env. Sto installando il XDocument in questo modo:

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

poi cerco di ottenere i valori:?

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

nullo

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

nullo

? Così urce.XPathSelectElement ("// ENV: source", oManager)

Ottiene il nodo correttamente

sto assumendo questo è qualcosa a che fare con me impostare il manager dello spazio dei nomi sbagliato, ma io non riesco a capire come sistemarlo. Qualsiasi aiuto sarebbe grande.

Grazie

risposta

15

Oltre alla nota corretta di @ Mads-Hansen, si ha il tipico problema di non definire un prefisso (non vuoto) per uno degli spazi dei nomi.

Ricorda: XPath considera qualsiasi nome non prefissato in "nessun spazio dei nomi".

Quindi questo è sbagliato:

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

Questo XPath vuole selezionare tutti kmsg elementi che sono in "nessun namespace" e seleziona in modo corretto nulla, perché qualsiasi kmsg elementi nel documento XML fornito sono nello spazio dei nomi "http://url1" e non in "nessun spazio dei nomi".

farlo correttamente:

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

del namespace-uri dichiarato in XML di origine non corrispondono allo spazio dei nomi URI di che si sta registrando con il XmlNamespaceManager.

Nel vostro XML di origine:

  1. Lo spazio dei nomi anonimi (senza prefisso) ha il namespace-uri: http://url1
  2. Il ENV prefisso namespace ha il namespace-uri: url1

Nel tuo XmlNamespaceManager hai dichiarato:

  1. Lo spazio dei nomi anonimi (senza prefisso) ha il namespace-uri: http://xml.kerridge.net/k8msg
  2. Il ENV prefisso namespace ha il namespace-uri: http://xml.kerridge.net/k8msgEnvelope

I valori namespace-uri devono corrispondere, altrimenti sei selezionando diversi nomi di elementi e non otterrà mai una corrispondenza.