2

I have an ugly block of XML that I am trying to parse in VB.net. Basically, I need to find a particular node, and then start grabbing all the info in that particular node that is hidden a few nodes deeper. I can construct something to find the node I want and select its child nodes into a nodelist. I can then loop through that nodelist and pull attributes from that nodelist, but I can't seem to find a way to make a new nodelist based upon a selected node. I have searched and failed to find an answer, so I think I am doing something fundamentally stupid. I basically need to grab all of the info in the <SixithLayer> and deeper and parse it up, but I have only been able to get information from the <SixithLayer>

My Code:

Imports System
Imports System.IO
Imports System.Xml
Public Class Form1
    Sub ExampleXML()
        Dim my_XML_doc As XmlDocument = New XmlDocument
        Dim first_node_list As XmlNodeList
        Dim second_node_list As XmlNodeList
        my_XML_doc.Load("C:\temp\xmlExample.xml")
        first_node_list = my_XML_doc.SelectNodes("/FirstLayer/SecondLayer/ThirdLayer//FourthLayer[@Type='Type D']//FifthLayer/*")
        For Each node In first_node_list
            Dim grab_first_layer_info = node.Attributes.GetNamedItem("Name").Value
            second_node_list = node.SelectNodes("ImportantInfo")
            For Each node2 In second_node_list
                Dim grab_second_layer_info = node.Attributes.GetNamedItem("Name").Value
                'Some more for looping here to get all the attributes and and innerXML values hidden in here
                'unless there is a better way to quickly grab stuff that might be a variable
                'number of nodes deeper with varied names.
            Next
        Next
    End Sub
End Class

My XML

<FirstLayer>
    <SecondLayer>
        <ThirdLayer>
            <FourthLayer Type="Type A" Name="FirstName"></FourthLayer>
            <FourthLayer Type="Type B" Name="SecondName"></FourthLayer>
            <FourthLayer Type="Type C" Name="ThirdName"></FourthLayer>
            <FourthLayer Type="Type D" Name="FourthName">
                <FifthLayer>
                    <SixthLayer Type="Step" Name="First">
                        <SomeJunk></SomeJunk>
                        <ImportantInfo Name="1stImportantStuff">
                            <StoreValue>
                                <Value>500</Value>
                            </StoreValue>
                            <MoreStuff Flavor="Purple" Look="Chocolate">
                                <Value>29</Value>
                            </MoreStuff>
                        </ImportantInfo>
                        <ImportantInfo Name="2ndImportantStuff">
                            <StoreValue>
                                <Value>TRUE</Value>
                            </StoreValue>
                        </ImportantInfo>
                        <ImportantInfo Name="3rdImportantStuff">
                            <StoreValue>
                                <Value>Cat</Value>
                            </StoreValue>
                        </ImportantInfo>
                    </SixthLayer>
                    <SixthLayer Type="Step" Name="Second">
                        <SomeJunk></SomeJunk>
                        <ImportantInfo Name="1stImportantStuff">
                            <StoreValue>
                                <Value>500</Value>
                            </StoreValue>
                        </ImportantInfo>
                        <ImportantInfo Name="2ndImportantStuff">
                            <StoreValue>
                                <Value>TRUE</Value>
                            </StoreValue>
                        </ImportantInfo>
                        <ImportantInfo Name="3rdImportantStuff">
                            <StoreValue>
                                <Value>Cat</Value>
                            </StoreValue>
                        </ImportantInfo>
                    </SixthLayer>
                </FifthLayer>
            </FourthLayer>
        </ThirdLayer>
    </SecondLayer>
</FirstLayer>

Thanks for any help.

Edit: Fixed it so that it so that the second loop works per the comments below. Not sure how I managed to miss that so thoroughly. Still curious if there is a better way to grab all of the attribute and innertext information that is in <ImportantStuff> and beyond besides looping deeper and deeper, but this is a pretty good start. Thanks for the help.

7
  • 1
    Use LINQ to XML instead of old XmlDocument. What exactly would you like to take from the XML? Commented Sep 9, 2013 at 16:50
  • Don't put the forward slash in front of SeventhNode. That forces it to go back up to the root element. Commented Sep 9, 2013 at 16:53
  • @MarcinJuraszek, as nice as LINQ is, it's a proprietary Microsoft technology. Many people, like myself, prefer XPath. XPath is very useful for many reasons. The fact that it is a standard technology employed by many other tools and languages, not least among them. You can use XPath via some extension methods on the XElement class, but there's certainly nothing wrong with XmlDocument. Commented Sep 9, 2013 at 16:56
  • I'm confused by what you are trying to do/what you are having trouble with. Your first XPath select, in your example, grabs all of the SixthLayer elements. Is that what you intended it to do? Then you try to select the SeventhNode, as if that were the name of a sub-element under the SixthLayer element. There is no such sub-element, so even if you didn't precede it with a slash, it still won't find anything based on your example. Commented Sep 9, 2013 at 17:14
  • If, for instance, you changed that second select to second_node_list = node.SelectNodes("ImportantInfo"), that would work to select all of the ImportantInfo elements under the current SixthLayer element, but it's not clear from your question if that's what you are attempting to do Commented Sep 9, 2013 at 17:18

2 Answers 2

1

I believe the way you are doing it is the easiest way. Even though it's kind of a pain, it's quicker than writing your own parser.

It might improve the code's readability if you move the inner for loop to another sub, and then probably use a separate sub for the inside of that loop.

Sign up to request clarification or add additional context in comments.

Comments

0

I was looking at various options and choose the best and easy approach.

I searched for LINQ to Xml and found interesting article which talks parsing XML. You can apply where clause in LINQ query as alternate solution.

Here is the article https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/concepts/linq/how-to-write-queries-on-xml-in-namespaces

Hope this helps. Thank you!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.