Houlahan
Houlahan

Reputation: 783

How to read a Version element value from an XML file

I'm trying to read the version of an xml file:

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

The code I'm trying to use is:

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

But, it doesent pull anything.

i changed it to:

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

and i just get

NullReferenceException was Unhandled Object reference not set to an instance of an object.

because the m_xmld.selectsinglenode is null

Upvotes: 0

Views: 1663

Answers (2)

Steven Doggart
Steven Doggart

Reputation: 43743

Your first problem is that you are trying to read the Version as an attribute instead of as a child element.

The second problem is that your XML document has a default namespace. That means that even though none of the elements explicitly specify a namespace prefix, they actually do belong to the urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01 namespace. As you may be aware, the SelectSingleNode method uses XPath to find the matching nodes. What you may not know, it that there is no way to force XPath to use a default namespace. As such, you need to specify the correct namespace for every node name that belongs to any namespace. To quote the relevant paragraph from the Official XPath Specification:

A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.

Therefore, you need to do something like this:

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

In this example, xmld.DocumentElement.NamespaceURI returns the default namespace URI for the root element (urn:schemas-basda-org:2000:purchaseOrder:xdr:3.01). We assign it the prefix of "n", so then we need to put an "n:" prefix on every element name in the XPath.

Also, you'll note that I changed the GetXmlVersion = line to Return. Using the Return keyword is the preferred method in VB.NET. Also, I changed the name of your m_xmld variable to xmld because it was confusing. Typically, when people prefix a variable name in VB with an m_, that is to indicate that it is a private field of the class (a private variable declared at the class level, outside of any method). That is not the case here. xmld is just a local method variable.

Upvotes: 2

Michael Kay
Michael Kay

Reputation: 163468

Version is a child element of Schema, not an attribute.

Upvotes: 0

Related Questions