2012-07-06 34 views
0

我試圖讀取XML文件的版本讀取版本元素值:如何從一個XML文件

<Order xsi:schemaLocation="urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01 order-v3.xsd urn:schemas-bossfed-co-uk:OP-Order-v1 OP-Order-v1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01"> 
    <OrderHead> 
    <Schema> 
     <Version>3.05</Version> 
    </Schema> 
    <Parameters> 
     <Language>en-GB</Language> 
     <DecimalSeparator>.</DecimalSeparator> 
     <Precision>12.1</Precision> 
    </Parameters> 
    <OrderCurrency> 
     <Currency Code="GBP">GB Pounds</Currency> 
    </OrderCurrency> 
    </OrderHead> 

我試圖使用的代碼是:

Dim m_xmld As XmlDocument 
Dim m_nodelist As XmlNodeList 
Dim m_node As XmlNode 

'Create the XML Document 
m_xmld = New XmlDocument() 

'Load the Xml file 
m_xmld.Load(fileLocation) 

'Show all data in your xml 
MessageBox.Show(m_xmld.OuterXml) 

'Get the list of name nodes 
m_nodelist = m_xmld.SelectNodes("/Order/OrderHead/Schema") 

For Each m_node In m_nodelist 
    GetXmlVersion = m_node.Attributes.GetNamedItem("Version").Value 
Next 

但是,它有任何東西拉。

我改成了:

Public Shared Function GetXmlVersion (ByVal fileLocation As String) As String 
    Dim m_xmld As XmlDocument = New XmlDocument() 
    m_xmld.Load (fileLocation) 
    GetXmlVersion = m_xmld.SelectSingleNode ("/Order/OrderHead/Schema/Version").InnerText 
End Function 

,我只是得到

的NullReferenceException是不設置到對象的實例未處理 對象引用。

因爲m_xmld.selectsinglenode爲空

+0

您沒有顯示出重現問題的XML的完整工作示例。當我測試它時,它工作正常,但爲了讓它起作用,我必須添加結束標籤並取出'xsi:schemaLocation'屬性,因爲該名稱空間未定義。特別是,你需要顯示默認的命名空間,如果有的話。如果定義了默認名稱空間,那肯定會停止您的代碼的工作。 – 2012-07-06 17:22:57

+0

我已經更新了XML,我沒有意識到schemaLocation影響了讀取xml節點。謝謝 – Houlahan 2012-07-06 17:34:46

+0

有無論如何,我可以閱讀這個XML而忽略模式?作爲我將與這個文件做的工作doesent需要訪問他們再次感謝 – Houlahan 2012-07-06 17:50:44

回答

2

你的第一個問題是,你想讀的版本爲屬性而不是作爲一個子元素。

的第二個問題是,你的XML文檔有一個默認的命名空間。這意味着即使沒有元素明確指定名稱空間前綴,它們實際上也屬於urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01名稱空間。如您所知,SelectSingleNode方法使用XPath來查找匹配的節點。您可能不知道的是,無法強制XPath使用默認名稱空間。因此,您需要爲屬於任何名稱空間的每個節點名稱指定正確的名稱空間。引述從Official XPath Specification有關段落:

的QName在節點測試擴展成使用 命名空間聲明從表達式上下文中的擴展名。這是相同的 的方式擴展在開始和結束標記 元素類型名做除了與的xmlns聲明默認命名空間不使用:如果 的QName沒有前綴,則命名空間URI爲空 (這個 與擴展屬性名稱的方式相同)。如果 QName的前綴在 表達式上下文中沒有名稱空間聲明,則會出錯。

因此,你需要做的是這樣的:

Public Shared Function GetXmlVersion(ByVal fileLocation As String) As String 
    Dim xmld As XmlDocument = New XmlDocument() 
    xmld.Load(fileLocation) 
    Dim manager As XmlNamespaceManager = New XmlNamespaceManager(xmld.NameTable) 
    manager.AddNamespace("n", xmld.DocumentElement.NamespaceURI) 
    Return xmld.SelectSingleNode("/n:Order/n:OrderHead/n:Schema/n:Version", manager).InnerText 
End Function 

在這個例子中,xmld.DocumentElement.NamespaceURI返回默認命名空間URI的根元素(urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01)。我們爲它分配前綴「n」,因此我們需要在XPath中的每個元素名稱上加上一個「n:」前綴。

而且,你會注意到,我改變了GetXmlVersion =Return。使用Return關鍵字是VB.NET中的首選方法。另外,我將m_xmld變量的名稱更改爲xmld,因爲它令人困惑。通常,當人們在VB中以m_作爲變量名稱前綴時,即表示它是該類的私有字段(在任何方法之外的類級別聲明的私有變量)。這裏情況不同。 xmld只是一個局部方法變量。

+0

感謝您的幫助我已經改變了我的原始文章我剛剛得到一個空引用錯誤,因爲查詢仍然存在任何東西 – Houlahan 2012-07-06 17:17:09

+0

@Houlahan謝謝,請參閱我的解決方案的更新答案。 – 2012-07-06 17:53:38

+0

優秀的解釋,非常感謝您的幫助! – Houlahan 2012-07-06 18:03:10

0

版本是模式的子元素,而不是一個屬性。

+0

就這樣! GetXmlVersion = m_node.ChildNodes(「Version」)。儘管如此,值仍然沒有任何效果。當m_nodelist =完成(「/ Order/OrderHead/Schema」)的選擇節點時什麼都沒有。謝謝 – Houlahan 2012-07-06 09:39:00