How to select particular node from XML

2019-09-02 16:54发布

问题:

I have this XML:

<?xml version="1.0"?>
    <Document xmlns="urn:somethinghere">
        <fapx.001.02>
            <Sts>
                <StsVal>ACCEPTED</StsVal>
            </Sts>
        </fapx.001.02>
    </Document>

I want to select value of "StsVal" and for that I wrote this code but getting error:

Code

Dim doc As XmlDocument = New XmlDocument()
doc.Load("myfile.xml")
Dim response As String = doc.SelectSingleNode("Document/fapx.001.02/Sts/StsVal").InnerText

Error

Object reference not set to an instance of an object.

EDIT

I know I am getting this error due to Nulll value probably because the path I have given in SelectSingleNode function is not correct. That's why I want to know how to give correct path based on given XML.

回答1:

That's because your XML has default namespace : xmlns="urn:somethinghere". This topic (XPath query against XML with default namespace) has been asked so many times previously in various forms here in SO. Here are some from my answer history :

  1. Parse XML with succint syntax
  2. Use XPath with XML namespace
  3. Get value of single node yields "... value of Nothing"

And this is one possible way to query element in namespace using XPath and XmlDocument :

Dim nsManager As New XmlNamespaceManager(New NameTable())
nsManager.AddNamespace("d", "urn:somethinghere")

Dim doc As XmlDocument = New XmlDocument()
doc.Load("myfile.xml")
Dim response As String = doc.SelectSingleNode("d:Document/d:fapx.001.02/d:Sts/d:StsVal", nsManager).InnerText


回答2:

Your problem is that your document has a default namespace, but the XPath expression doesn't use it. You can pass in a namespace manager and use an alias for the namespace like this:

Dim xnm as XmlNamespaceManager = New XmlNamespaceManager( doc.NameTable )
xnm.AddNamespace("ns", "urn:somethinghere")
Dim response As String = doc.SelectSingleNode("ns:Document/ns:fapx.001.02/ns:Sts/ns:StsVal", xnm).InnerText

My vb's a little rusty, apologies if the syntax needs a little adjustment, but hopefully you get the idea. The "ns" is abritrary, you can use anything you want as a temporary prefix.

It feels like there should be a way of getting it to recognize the default namespace, but for some reason adding the documents nametable on it's own doesn't seem to recognize it, but giving it a name will work.