2009-06-09 77 views
1

XML新手。我有第三方Web服務,提供一個XML文檔,我必須更新元素值並傳回。核心問題是在下面的代碼中調用node.RemoveAll()方法時出現NullReferenceException錯誤。我調用RemoveAll()方法是因爲每個元素在提供給我時都具有xsi:nil屬性,並且如果在更新元素值之前不刪除它,則XML將不會由webservice驗證。在XML文檔中選擇節點時返回空值

由第三方Web服務提供的XML文檔如下:我已經看到了使用XmlNamespaceManager的

<?xml version="1.0" encoding="utf-16"?> 
<TaskData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.sample.com/application/1/520800B"> 
    <Global> 
    <RequestInfo xmlns="http://schema.sample.com/application/1/Types"> 
     <Requestor xsi:nil="true" /> 
     <Date_init xsi:nil="true" /> 
     <Shipto xsi:nil="true" /> 
     <Customer xsi:nil="true" /> 
     <Contact xsi:nil="true" /> 
     <Requestor_Email xsi:nil="true" />  
    </RequestInfo>  
    </Global> 
    </TaskData> 

其他的解決方案,但我一直無法使它發揮作用。此xml文檔具有爲TaskData元素指定的名稱空間以及用於RequestInfo元素的不同名稱空間。我試着爲每個命名空間指定XmlNamespaceManager變量,但得到了相同的結果....在中斷模式下懸停在nsmgr變量上顯示「子項無法評估」,並且DefaultNamespace屬性爲空字符串。

Public Sub testxml() 

    Dim doc As New XmlDocument 
    doc.Load("c:\temp\sample.xml") 

    Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable) 
    nsmgr.AddNamespace("s", "http://schema.sample.com/application/1/520800B") 

    Dim node As XmlNode = doc.SelectSingleNode("s:Requestor", nsmgr) 
    node.RemoveAll() 
    node.InnerText = "Your Name Goes Here" 

    doc.Save("c:\temp\sample.xml") 

End Sub 

回答

2

的問題是這樣的說法:

doc.SelectSingleNode("s:Requestor", nsmgr) 

你需要做的是

doc.SelectSingleNode("//s:Requestor",nsmgr) 

「S:請求方」指給我當前節點名S下面的節點:請求者

「// s:Requestor」表示給我名爲s的文檔中的所有節點:請求者

如果你想忽略名字空間你可以做

doc.SelectSingleNode("//*[local-name()='Requestor']") 
+1

神話般的格雷格!忽略你建議的NS工作的選項是我喜歡的,因爲我無法控制第三方webservice分配的命名空間。我嘗試了「// s:Requestor」,但沒有奏效。 – Don 2009-06-09 21:54:55

0

我不知道我是否已正確理解您的任務。但是,如果你要只是刪除XSI:無=「真」的一部分,你爲什麼不加載它作爲一個字符串,並調用

string.replace("xsi:nil=\"true\"", "") 

當然這不是最乾淨的解決方案,但我不能但對C#的XML處理API感到滿意,所以我不得不諮詢MSDN以習慣。也許這已經解決了你的問題。

+0

謝謝,Juri。我遇到的問題是變量「節點」沒有被設置,並且調用RemoveAll()方法時,它會拋出異常。你能否看到我的XPath語法有什麼問題,以便將「節點」變量設置爲正確的元素? – Don 2009-06-09 21:38:59

0

你的代碼有兩個錯誤。一個是用於選擇節點的XPath(正如Greg指出的那樣)。第二個是名字空間。我可能是錯的,但我解釋XML文檔TaskData元素具有以下命名空間聲明:

xmlns="http://schema.sample.com/application/1/520800B" 

...它設置爲無前綴元素的名稱空間。

但隨後RequestInfo標籤有這個命名空間聲明:

xmlns="http://schema.sample.com/application/1/Types" 

所以RequestInfo標籤內,有一個沒有前綴標記另一個命名空間。在你的代碼中,你使用這兩個命名空間中的第一個來匹配駐留在第二個標籤中的標籤,這將無法實現。有兩種方法可以解決它。一個是簡單地更改命名空間在代碼:

​​

第二個是定義兩個命名空間,並使用所指出的完整路徑的標籤XPath表達式:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 
nsmgr.AddNamespace("r", "http://schema.sample.com/application/1/520800B"); 
nsmgr.AddNamespace("s", "http://schema.sample.com/application/1/Types"); 
XmlNode node = doc.SelectSingleNode(@"/r:TaskData/r:Global/s:RequestInfo/s:Requestor", nsmgr); 

兩個這些情況導致相同的結果; node不是null

+0

Fredrik,我喜歡有能力指定元素的完整路徑。由於這是我的第一篇文章,我還沒有足夠的聲望來對您的答案進行投票,但它非常有用,謝謝! – Don 2009-06-09 22:38:01

0

你應該能夠在你的selectelement調用中禁止任何命名空間調用,我寧願循環訪問我的文檔..但這只是我。