0

我正在尝试读取 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 为空

4

2 回答 2

2

您的第一个问题是您试图将 Version 作为属性而不是子元素读取。

第二个问题是您的 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返回根元素 ( urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01) 的默认命名空间 URI。我们为其分配前缀“n”,因此我们需要在 XPath 中的每个元素名称上放置一个“n:”前缀。

另外,您会注意到我将GetXmlVersion =行更改为Return. 使用Return关键字是 VB.NET 中的首选方法。另外,我将您的m_xmld变量名称更改为,xmld因为它令人困惑。通常,当人们在 VB 中为变量名称添加前缀时m_,表示它是类的私有字段(在类级别声明的私有变量,在任何方法之外)。这里情况不同。 xmld只是一个局部方法变量。

于 2012-07-06T12:51:06.480 回答
0

版本是 Schema 的子元素,而不是属性。

于 2012-07-06T09:01:22.853 回答