Link to home
Start Free TrialLog in
Avatar of nahumba
nahumba

asked on

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!
Avatar of drichards
drichards

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
Avatar of nahumba

ASKER

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!!!
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
Avatar of nahumba

ASKER

For some reason "nl" is always empty, I'm using the xml file which I've posted here earlier...
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
Avatar of nahumba

ASKER

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?
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
Replace:

    Dim writer As New XmlTextWriter(OutputFileName, Nothing)

with

    Dim writer As New XmlTextWriter(OutputFileName, System.Text.UTF8Encoding.UTF8) ' For UTF8 encoding
Avatar of nahumba

ASKER

Hi, I just did, still not working :(
I don't understand whats wrong...
Avatar of nahumba

ASKER

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...
Avatar of nahumba

ASKER

Tried everything, seems like some sort of formatting problem which I don't know how to solve...
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
ASKER CERTIFIED SOLUTION
Avatar of drichards
drichards

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you want to keep your own index count, you can put that code back, but I don't think you need it.
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.
Avatar of nahumba

ASKER

Thanks! it works

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

best regards,
nahumba