smt
smt

Reputation: 267

Get XML data with random Id nodes

I would like to read a specific node of my XML but I am having problems on how to focus the problem.

Right now the XML file has this structure:

<?xml version="1.0" encoding="utf-8"?>
<Assessment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmlns:xsd="http://www.w3.org/2001/XMLSchema"   xmlns="http://www1.macadam.eu/Webservices/FleetCarV3/">
 <Damages>
 <Damage>
  <Id>15724669</Id>
  <AssessmentId>1959065</AssessmentId>
  <Location>
   <Id>5</Id>
    <DescriptionEN>Panel R R</DescriptionEN>
    <DescriptionNL>Panneel A R</DescriptionNL>
    <DescriptionFR>Panneau ARD</DescriptionFR>
    <DescriptionDE>Panel HR</DescriptionDE>
    <DescriptionES>Panel TRAS DR</DescriptionES>
  </Location>
  <Type>
    <Id>1274</Id>
    <DescriptionEN>Bump(s)</DescriptionEN>
    <DescriptionNL>Deuk(en)</DescriptionNL>
    <DescriptionFR>Bosse(s)</DescriptionFR>
    <DescriptionDE>Dell(en)</DescriptionDE>
    <DescriptionES>Abolladuras</DescriptionES>
  </Type>
  <Repair>
    <Id>1307</Id>
    <DescriptionEN>Le - Replace and paint</DescriptionEN>
    <DescriptionNL>Le - Vervangen en spuiten</DescriptionNL>
    <DescriptionFR>Le - Remplacer et peindre</DescriptionFR>
    <DescriptionDE>Erneuern + lackieren</DescriptionDE>
    <DescriptionES>Le - Reemplazar Y Pintar</DescriptionES>
  </Repair>
  <Comment />
 </Damage>
 <Damage>
   ...
   ...
 </Damage>
 <Damage>
   ...
   ...
 </Damage>
 </Damages>
</Assessment>

Note that I put more <Damage> tags. Each <Id> is different per <Damage> node, and what I need is the text inside <DescriptionES> nodes.

Below is code trying to get the <Location> node:

nsmgr = New XmlNamespaceManager(m_xmld.NameTable)
nsmgr.AddNamespace("sd", "http://www1.macadam.eu/Webservices/FleetCarV3/")

m_nodelist = m_xmld.DocumentElement.SelectNodes("/sd:Assessment/sd:Damages/sd:Damage/sd:Location", nsmgr)
For Each m_node In m_nodelist
    For j = 0 To 5000
        Dim Location = m_node.SelectSingleNode("/sd:Assessment/sd:Damages/sd:Damage/sd:Location[sd:Id=" & j & "]", nsmgr).InnerText
        If Location IsNot Nothing Then
            MsgBox("i'm in")
            'txtDamageReport.Text = Location
        End If
    Next j
Next

It does not work, as expected. I don't know how to continue.

Upvotes: 0

Views: 133

Answers (2)

Fabio
Fabio

Reputation: 32455

You can use LINQ to XML which have little bid easy to understand API and better readability

Dim document As XDocument = XDocument.Load(pathToTheFile)
Dim ns = XNamespace.Get("http://www1.macadam.eu/Webservices/FleetCarV3/")

For Each damage As XElement in document.Descendants(ns + "Damage")
    Dim damageId = damage.Element(ns + "Id").Value
    Dim locationDescription = damage.Element(ns + "Location").
                                     Element(ns + "DescriptionES").
                                     Value

    MessageBox.Show($"Id = {damageId};  Desc = {locationDescription}")
Next

vb.net have possibility to use XML Axis Properties, which can be useful if you have a schema for the xml files, then you will get IntelliSense support for element names.
Same code as above by using Axis properties.
For using axis properties with namespace you need import namespace to the file

Imports <xmlns:ns="http://www1.macadam.eu/Webservices/FleetCarV3/">  

For Each damage As XElement in document...<ns:Damage>
    Dim damageId = damage.<ns:Id>.Value
    Dim locationDescription = damage.<ns:Location>.<ns:DescriptionES>.Value

    MessageBox.Show($"Id = {damageId};  Desc = {locationDescription}")
Next

Upvotes: 1

chateaur
chateaur

Reputation: 356

You can use VB XmlDocument as follows. I believe that the XmlNamespaceManager is wrong in your code but since you didn't provide it ...

This works for me :

Dim doc As New XmlDocument

doc.Load(path)

//Add a namespace to all the document
Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
        nsmgr.AddNamespace("g", "http://www1.macadam.eu/Webservices/FleetCarV3/")

Dim nodeList As XmlNodeList
Dim root As XmlElement = doc.DocumentElement
nodeList = root.SelectNodes("//g:Assessment//g:Damages//g:Damage//g:Location", nsmgr)

// Loop over damage section
For Each damageNode As XmlNode In nodeList
     Dim id As String = damageNode.SelectSingleNode("//g:Id", nsmgr).InnerText
     Dim desc As String = damageNode.SelectSingleNode("//g:DescriptionES", nsmgr).InnerText

      MsgBox(id & vbCrLf & desc)
Next

Upvotes: 0

Related Questions