• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 526
  • Last Modified:

Read child attributes - XML & vb.net

Hi all,
I have an XML file which looks like this:
SETTINGS>
      <OSRS>

<Item index="0">
<Index>0</Index>
<ObjectName>aaa</ObjectName>
<Permissions>ListDirectory, ReadAndExecute</Permissions>
<Groups>Authenticated Users, Guests</Groups>
</Item>

<Item index="1">
<Index>0</Index>
<ObjectName>aaa</ObjectName>
<Permissions>ListDirectory, ReadAndExecute</Permissions>
<Groups>Authenticated Users, Guests</Groups>
</Item>

<Item index="2">
<Index>1</Index>
<ObjectName>aaadds</ObjectName>
<Permissions>ListDirectory, ReadAndExecute</Permissions>
<Groups>Authenticated Users, Guests</Groups>
</Item>
     
    </OSRS>
</SETTINGS>

I would like to read the Items under "\SETTINGS\OSRS" in vb.net.

How can this be done?

Thanks in advance!
0
nahumba
Asked:
nahumba
  • 7
  • 7
  • 3
1 Solution
 
drichardsCommented:
Here are two possibilities:

1) Read whole doc and extract Item elements:

        Dim xdoc As XmlDocument = New XmlDocument()
        xdoc.Load("<xml file name>")
        Dim nl As XmlNodeList = xdoc.SelectNodes("SETTINGS/OSRS/Item")


2) Read through the doc and stop to process each Item node:

        Dim xr As XmlReader = New XmlTextReader(New System.IO.FileStream<xml file name>", FileMode.Open))
        While xr.Read
            If xr.Name = "Item" Then
                'Process the Item element
            End If
        End While
0
 
nahumbaAuthor Commented:
Hi drichards, can you give me more details on using the method number (1)? Using this method, will I be able to extract the tags under the "Item" elements? Somthing like this:

<Item index="1">
<Index>0</Index>
<ObjectName>aaa</ObjectName>
<Permissions>ListDirectory, ReadAndExecute</Permissions>
<Groups>Authenticated Users, Guests</Groups>
</Item>

Thanks again!!!
0
 
drichardsCommented:
In a console app, for example, you could write all the part names to the screen using the NodeList you got from SelectNodes:

        For Each node As XmlNode In nl
            Console.WriteLine(node.Attributes(0).Name)
            Console.WriteLine(node.Attributes(0).Value)  'You could use InnerText in place of Value
            For Each childNode As XmlNode In node.ChildNodes
                Console.WriteLine(childNode.Name)
                Console.WriteLine(childNode.InnerText) 'Elements need to use InnerText, not Value
            Next
        Next
0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 
nahumbaAuthor Commented:
For some reason "nl" is always empty, I'm using the xml file which I've posted here earlier...
0
 
drichardsCommented:
Here's the XML file I used to test (just copied from your original post and added opening '<'):

<?xml version="1.0" encoding="utf-8" ?>
<SETTINGS>
  <OSRS>

    <Item index="0">
      <Index>0</Index>
      <ObjectName>aaa</ObjectName>
      <Permissions>ListDirectory, ReadAndExecute</Permissions>
      <Groups>Authenticated Users, Guests</Groups>
    </Item>

    <Item index="1">
      <Index>0</Index>
      <ObjectName>aaa</ObjectName>
      <Permissions>ListDirectory, ReadAndExecute</Permissions>
      <Groups>Authenticated Users, Guests</Groups>
    </Item>

    <Item index="2">
      <Index>1</Index>
      <ObjectName>aaadds</ObjectName>
      <Permissions>ListDirectory, ReadAndExecute</Permissions>
      <Groups>Authenticated Users, Guests</Groups>
    </Item>

  </OSRS>
</SETTINGS>


and here's the complete code - be sure to replace the file name with the one you are using:

        Dim xdoc As XmlDocument = New XmlDocument()
        xdoc.Load("..\..\XmlFile1.xml") 'Replace with your file name
        Dim nl As XmlNodeList = xdoc.SelectNodes("SETTINGS/OSRS/Item")
        For Each node As XmlNode In nl
            Console.WriteLine(node.Attributes(0).Name)
            Console.WriteLine(node.Attributes(0).Value)
            For Each childNode As XmlNode In node.ChildNodes
                Console.WriteLine(childNode.Name)
                Console.WriteLine(childNode.InnerText)
            Next
        Next
0
 
nahumbaAuthor Commented:
Great! almost there, as I see the only problem is with the encoding declaration which I don't know how to put in my document... this is how I write it:

Dim writer As New XmlTextWriter(OutputFileName, Nothing)
       
 Dim ItemIndex As Integer

        writer.WriteStartDocument()



        ItemIndex = 0

        writer.WriteStartElement("SETTINGS")
        writer.WriteStartElement("OSRS")

        For Each item As ListViewItem In ListViewControl.Items

            writer.WriteStartElement("Item", item.Index)
            writer.WriteAttributeString("index", item.Index)




            writer.WriteStartElement("Index", "")
            writer.WriteString(ListViewControl.Items(ItemIndex).Tag)
            writer.WriteEndElement()

            writer.WriteStartElement("ObjectName", "")
            writer.WriteString(ListViewControl.Items(ItemIndex).Text)
            writer.WriteEndElement()

            writer.WriteStartElement("Permissions", "")
            writer.WriteString(ListViewControl.Items(ItemIndex).SubItems.Item(1).Text)
            writer.WriteEndElement()

            writer.WriteStartElement("Groups", "")
            writer.WriteString(ListViewControl.Items(ItemIndex).SubItems.Item(2).Text)
            writer.WriteEndElement()
            writer.WriteEndElement()

            ItemIndex = ItemIndex + 1
        Next

What exactly should I add here to make it work?
0
 
vbturboCommented:
Hi (not for the points)

Here is a code  to loop trough a xml.file - which allows you to read the data into a datatable.
It's somewhat similar to drichards suggestion.

place a datagridview on u r form and name it .....dgvalutakurser

    Private Sub RetriveXmlData()

        Dim reader As XmlTextReader = New System.Xml.XmlTextReader("http://www.nationalbanken.dk/dndk/valuta.nsf/valuta.xml")

'Or change it to a local file path  ("c:\myfile.xml")

        Dim dtbl As New DataTable
        Dim dr As DataRow
        Dim dv As New DataView(dtbl)

        Dim objNodes As New System.Xml.XmlDocument
        objNodes.Load(reader)
        Dim oNodes As System.Xml.XmlNodeList
        oNodes = objNodes.SelectNodes("//currency")

        dtbl.Columns.Add(New DataColumn("Valuta", GetType(String)))

        dtbl.Columns.Add(New DataColumn("Kurs", GetType(String)))

        Dim node As System.Xml.XmlNode

        For Each node In oNodes
            'modify it to select only the attributes that interest's you
            dr = dtbl.NewRow()
            dr(0) = node.Attributes.GetNamedItem("desc").Value
            dr(1) = node.Attributes.GetNamedItem("rate").Value
            dtbl.Rows.Add(dr)

        Next


        dgvalutakurser.DataSource = dv

        'dgvalutakurser.DataBind()

    End Sub

hope that helps

vbturbo
0
 
drichardsCommented:
Replace:

    Dim writer As New XmlTextWriter(OutputFileName, Nothing)

with

    Dim writer As New XmlTextWriter(OutputFileName, System.Text.UTF8Encoding.UTF8) ' For UTF8 encoding
0
 
nahumbaAuthor Commented:
Hi, I just did, still not working :(
I don't understand whats wrong...
0
 
nahumbaAuthor Commented:
by opening the xml file in notepad, i've noticed that there is a value called "xlmns"
xmlns="0"

near each "Item" value... Whats that? I suspect that this is causing the problem...
0
 
nahumbaAuthor Commented:
Tried everything, seems like some sort of formatting problem which I don't know how to solve...
0
 
vbturboCommented:
a different approach

If your ListView is bound to a dataset , then write the dataset to a xml file
DsWrite.xml("c:\myfile.xml")

else study this link
http://www.15seconds.com/issue/050615.htm

vbturbo
0
 
drichardsCommented:
I didn't look closely before - you are using the form of WriteStartElement that takes a namespace parameter.  Don't use the second parameter.

Here is more concise code since you don't need all the Start/End element calls to do what you want:


        Dim writer As New XmlTextWriter("E:\zztestxml.xml", System.Text.UTF8Encoding.UTF8)

        writer.WriteStartDocument()

        writer.WriteStartElement("SETTINGS")
        writer.WriteStartElement("OSRS")

        For Each item As ListViewItem In ListView1.Items

            writer.WriteStartElement("Item")
            writer.WriteAttributeString("index", item.Index)

            writer.WriteElementString("Index", item.Index)

            writer.WriteElementString("ObjectName", item.Text)

            writer.WriteElementString("Permissions", item.SubItems.Item(1).Text)

            writer.WriteStartElement("Groups", item.SubItems.Item(2).Text)

            writer.WriteEndElement()
        Next

        writer.Close()
0
 
drichardsCommented:
If you want to keep your own index count, you can put that code back, but I don't think you need it.
0
 
drichardsCommented:
vbturbo's soluton is a good one if you are alreadyt using a dataset bound to the listbox and the dataset does not contain items that you don't want to serialize into the XML.
0
 
nahumbaAuthor Commented:
Thanks! it works

sorry for all this mess which I've caused :-)

best regards,
nahumba
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 7
  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now