smt
smt

Reputation: 267

Parse XML containing namespaces in VB.Net

I found several related questions, but none of them give me a way to get it working.

I have a XML file with this structure:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfAssessmentItemTimed xmlns:xsi="http://a.b.c/" xmlns:xsd="http://d.e.f" xmlns="http://g.h.i">
  <AssessmentItemTimed>
    <CustomerId>306</CustomerId>
    <AssessmentId>1959060</AssessmentId>
    <ExternalReference />
    <License>0577HJK</License>
    <ChassisNumber>VF1KT1RG646667276</ChassisNumber>
    <CostTraditional>2771.16</CostTraditional>
    <CostCommercial>2771.16</CostCommercial>
    <Kilometers>90957</Kilometers>
    <TimeOrdered>2017-02-13T16:31:00.48</TimeOrdered>
    <TimeClosed>2017-02-17T17:09:43.14</TimeClosed>
  </AssessmentItemTimed>
  <AssessmentItemTimed>
    <CustomerId>306</CustomerId>
    <AssessmentId>1959061</AssessmentId>
    <ExternalReference />
    <License>0918HHM</License>
    <ChassisNumber>VF1KT1RG646272649</ChassisNumber>
    <CostTraditional>3293.33</CostTraditional>
    <CostCommercial>3293.33</CostCommercial>
    <Kilometers>158142</Kilometers>
    <TimeOrdered>2017-02-13T16:31:01.73</TimeOrdered>
    <TimeClosed>2017-02-16T21:05:38.98</TimeClosed>
  </AssessmentItemTimed>
 </ArrayOfAssessmentItemTimed>

I can only get the data needed if I remove the namespaces from tag. This is my current code:

    Dim xmlnode As XmlDocument
    Dim nodeList As XmlNodeList
    Dim node As XmlNode
    Dim nsmgr As XmlNamespaceManager

    Try

        xmlnode = New XmlDocument()
        xmlnode.Load("file.xml")
        nsmgr = New XmlNamespaceManager(xmlnode .NameTable)

        nodeList = xmlnode.DocumentElement.SelectNodes("/sd:ArrayOfAssessmentItemTimed/sd:AssessmentItemTimed", nsmgr)

        For Each xmlnode In nodeList 

            Dim plateNumber = xmlnode.SelectSingleNode("sd:License", nsmgr).InnerText
            Dim chassisNumber = xmlnode.SelectSingleNode("sd:ChassisNumber", nsmgr).InnerText
            Dim Kilometers = mlnode.SelectSingleNode("sd:Kilometers", nsmgr).InnerText

            'test if works
            MsgBox("License: " & plateNumber & vbCrLf _
                       & "Chassis: " & chassisNumber & vbCrLf _
                       & "Kms: " & Kilometers & vbCrLf & vbCrLf
                       )
        Next
    Catch errorVariable As Exception
        'Error trapping
        MsgBox(errorVariable.ToString())
    End Try

Which could be the correct way to exclude xmlns values? I really don't understand XmlNamespaceManager so I can't get a positive result.

Thank you for all your suggestions.

Upvotes: 1

Views: 3900

Answers (2)

Slai
Slai

Reputation: 22876

You can check How to: Declare and Use XML Namespace Prefixes for a simpler alternative.

Imports <xmlns="http://g.h.i">

and sample use:

'' Dim xDoc = System.Xml.Linq.XDocument.Load("file.xml")

Dim xDoc = <?xml version="1.0" encoding="utf-8"?>
           <ArrayOfAssessmentItemTimed xmlns:xsi="http://a.b.c/"
               xmlns:xsd="http://d.e.f" xmlns="http://g.h.i">
               <AssessmentItemTimed>
                   <License>0577HJK</License>
                   <ChassisNumber>VF1KT1RG646667276</ChassisNumber>
                   <Kilometers>90957</Kilometers>
               </AssessmentItemTimed>
               <AssessmentItemTimed>
                   <License>0918HHM</License>
                   <ChassisNumber>VF1KT1RG646272649</ChassisNumber>
                   <Kilometers>158142</Kilometers>
               </AssessmentItemTimed>
           </ArrayOfAssessmentItemTimed>

For Each x In xDoc.<ArrayOfAssessmentItemTimed>.<AssessmentItemTimed>

    MsgBox("License: " & vbTab & x.<License>.Value & vbLf &
           "Chassis: " & vbTab & x.<ChassisNumber>.Value & vbLf &
           "Kms:     " & vbTab & x.<Kilometers>.Value & vbLf)
Next

Upvotes: 0

har07
har07

Reputation: 89295

You need to register the prefix 'sd' using XmlNamespaceManager before you can use it in XPath query. Make sure you map the prefix to the default namespace http://g.h.i :

....
nsmgr = New XmlNamespaceManager(New XmlNameTable())
nsmgr.AddNamespace("sd", "http://g.h.i");

nodeList = xmlnode.DocumentElement.SelectNodes("/sd:ArrayOfAssessmentItemTimed/sd:AssessmentItemTimed", nsmgr)
....

XPath always treat element without prefix as an element with empty namespace, it doesn't have a notion of default namespace (only XML has), that's why you need to made up the prefix 'sd' here.

Upvotes: 2

Related Questions