0

I have an XML document which I would like to use the attributes from each node with a structure like so:

<level1 attr1="value" attr2="value">
   <level2 attr3="value">
      <level3 attr1="value" attr3="value">
      </level3>
    </level2>
   <level2 attr3="value">
      <level3 attr1="value" attr3="value">
      </level3>
   </level2>
   <level2 attr3="value">
      <level3 attr1="value" attr3="value">
      </level3>
   </level2>
</level1>
<level1>
    ....
</level1>

I am trying to loop through each node in the file and record the information from the attributes.

Code:

Dim xml As New XDocument
Dim root As New XElement
xml = XDocument.Load(myFileLoc)
root = xml.Root

For Each level1 in root.Descendants()
    'Do Something with level1 attr'
    For Each level2 in level1.Descendants()
        'Do Something with level2 attr'
         For Each level3 in level2.Descendants()
             'Do Something with level3 attr'
         Next
    Next
Next

I learned quickly that this will loop through the entire document several times because level1 in root.Descendants() will also be all children level2s and level3s.

How can I limit each level1/level2/level3 to only the current node depth? Or, how should I be doing this kind of work?

Bugs
  • 4,491
  • 9
  • 32
  • 41
h01001000
  • 261
  • 8
  • 20

3 Answers3

0

Why aren't you using root.ChildNodes?

Descendants of a node means all child nodes, then the child nodes' child nodes, and so on.

Your problem should be solved if you use ChildNodes since it accesses only one level deep. Also use HasChildNodes to check if child nodes are present.

Bugs
  • 4,491
  • 9
  • 32
  • 41
user238607
  • 1,580
  • 3
  • 13
  • 18
  • Thanks for looking at my question. However, VS is telling me that `ChildNodes` and `HasChildNodes` are not members of 'System.Xml.Linq.XElement'. Maybe I need to do an import to use those? I think I've found a solution though, `root.Elements()` should return what I was looking for. – h01001000 May 04 '17 at 18:26
0

Mark provided what I was looking for, thank you. Using Elements() rather than Descendants() provided the nodes I was looking to loop through at each level.

Dim xml As New XDocument
Dim root As New XElement
xml = XDocument.Load(myFileLoc)
root = xml.Root

For Each level1 in root.Elements()
    'Do Something with level1 attr'
    For Each level2 in level1.Elements()
        'Do Something with level2 attr'
         For Each level3 in level2.Elements()
             'Do Something with level3 attr'
         Next
    Next
Next
h01001000
  • 261
  • 8
  • 20
0

I prefer using XElement

    Dim xe As XElement
    ' to load from a file
    ' Dim yourpath As String = "your path here"
    'xe = XElement.Load(yourpath)

    ' for testing
    xe = <root>
             <level1 attr1="value1" attr2="value2">
                 <level2 attr3="valueQ">
                     <level3 attr1="value3" attr3="value4">
                     </level3>
                 </level2>
                 <level2 attr3="value5">
                     <level3 attr1="value6" attr3="value7">
                     </level3>
                 </level2>
                 <level2 attr3="value8">
                     <level3 attr1="value9" attr3="value10">
                     </level3>
                 </level2>
             </level1>
             <level1 attr1="value11" attr2="value12"></level1>
         </root>

    For Each el1 As XElement In xe...<level1>
        Debug.WriteLine(el1.@attr1)
        For Each el2 As XElement In el1...<level2>
            Debug.WriteLine(el2.@attr3)
            For Each el3 As XElement In el2...<level3>
                Debug.WriteLine(el3.@attr3)
            Next
        Next
    Next

    ' to save file
    ' xe.Save(yourpath)
dbasnett
  • 11,334
  • 2
  • 25
  • 33