2010-09-15 36 views
8

我有一個看起來像這樣的XML文檔:怪誕用的XDocument,XPath和命名空間

<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命名空間中的項保留空值。我設立的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)

?Source.XPathSelectElement( 「//頭」,oManager)

?所以, urce.XPathSelectElement(「// ENV:來源」,oManager)

獲取節點正確

我假定這是一件與我建立命名空間管理錯誤的,但我想不出如何解決它。任何幫助都會很棒。

感謝

回答

15

除了@ Mads-Hansen的正確評論之外,您還有一個典型問題,就是沒有爲其中一個名稱空間定義(非空)前綴。

請記住:XPath認爲任何沒有前綴的名稱都在「no namespace」中。

因此這是錯誤

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

此XPath表達式要選擇所有kmsg元素都在「沒有命名空間」並正確選擇什麼,因爲提供的XML文檔中的任何kmsg元素在"http://url1"名稱空間中,而不在「無名稱空間」中。

要正確做到這一點:

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

命名空間URI在源XML不匹配的命名空間URI的是你與你的XmlNamespaceManager註冊聲明。

在源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值必須匹配,否則你選擇不同的元素名稱並永遠不會匹配。