Reading XML document issues.

exiletgm

Member
Joined
May 14, 2007
Messages
14
Programming Experience
1-3
Okay, I'm having issues reading this xml sheet with VB2005.

VB.NET:
<?xml version="1.0" encoding="utf-8" ?>
<Addressing>
     <Type name="US 1">
          <Name needs="1">1_ADD</Name>
          <Name needs="2">2_ADD</Name>
          <Name needs="3">3_ADD</Name>
          <Name needs="4">4_ADD</Name>
          <Name needs="5">5_DIR</Name>
          <Name needs="6">6_TYPE</Name>
          <Name needs="7">7_NAM</Name>
          <Name needs="8">8_TYPE</Name>
          <Name needs="9">9_DIR</Name>
     </Type>
     <Type name="US One A">
          <Name needs="A">A_NUM</Name>
          <Name needs="B">B_DIR</Name>
          <Name needs="C"></Name>
          <Name needs="D">D_NAM</Name>
          <Name needs="E">e_TYPE</Name>
          <Name needs="F">F_DIR</Name>
     </Type>
     <Type name="Single Field">
          <Name needs="Key Field">KEY</Name>
     </Type>
</Addressing>

I was able to populate Combobox1 easily enough with this code.
VB.NET:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' We will start with the make combo box
        ComboBox1.Items.Clear()
        docXML.Load("fieldmapping.xml")
        Dim nodRoot As XmlElement = docXML.DocumentElement
        Dim nodItems As XmlNodeList = nodRoot.GetElementsByTagName("Type")
Make combo box
        Dim i As Integer
        For i = 0 To nodItems.Count - 1 Step 1
            ComboBox1.Items.Add(nodItems.ItemOf(i).Attributes.ItemOf("name").InnerText)
        Next
    End Sub

Now I'm having issues populating a bunch of text boxes and labels on IndexChange. I have created an array of text boxes and labels using "ControlArrayUtils" that I found while digging on the internet. I was able to get a hack of sorts working to populate 1-9 in the labels but it wouldn't change when I would select a different item in the combobox1. The code below is an attempt to get it working but I'm against a wall and I'm tired of beating my head against it :p
VB.NET:
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
        ' Get the item that was selected
        Dim strAddType As String = Me.ComboBox1.Text()
        Dim txtName As TextBox() = CType(ControlArrayUtils.getControlArray(Me, "txtName"), TextBox())
        Dim lblName As Label() = CType(ControlArrayUtils.getControlArray(Me, "lblName"), Label())

        ' Create a list of the nodes we will need to locate
        Dim eleRoot As XmlElement = docXML.DocumentElement
        Dim nodType As XmlNodeList = eleRoot.GetElementsByTagName("Type")
        Dim nodName As XmlNodeList = eleRoot.GetElementsByTagName("Name")
        '  Dim atrType As XmlAttribute = nodType.ItemOf(i).Attributes("name")


        Dim i As Integer
        For i = 0 To nodType.Count - 1 Step 1
            Try
                If (nodType.ItemOf(i).InnerXml = strAddType) Then
                    Dim atrName As XmlAttribute = nodType.ItemOf(i).Attributes("needs")
                    Dim strName As String = nodName.ItemOf(i).Attributes.ItemOf("needs").InnerText
                    MsgBox(strName)
                    lblName(i).Text = strName
                    'txtName(i).Text = xmlNL.ItemOf(i).
                End If
            Catch ex As Exception
                System.Diagnostics.Debug.WriteLine(ex.Message)
                MsgBox(ex.Message)
            End Try
        Next
End Sub

Any help would be greatly appreciated.

Oh and the source code for the controls array can be found at http://www.codeproject.com/vb/net/control_arrays_in_vbnet.asp if its needed.

Thanks again!
 
This doesn't make sense: If nodType.ItemOf(i).InnerXml = strAddType
'strAddType' is one of the name attributes of Type nodes, why are you comparing to the InnerXml? When you want to select the same Type node just do that initially:
VB.NET:
Dim xpath As String = String.Format("//Type[@name='{0}']", strAddType)
Dim theTypeNode As Xml.XmlNode = docXML.DocumentElement.SelectSingleNode(xpath)
 
Actually 'strAddType' is that value of the text that has been selected in the combo box. I'm trying to populate the other labels and text boxes when something is selected in the combo box. I figured some sort of comparison of the parent node was required to get the child nodes, but the implementation is eluding me.
 
Your combobox lists "US 1", "US One A" and "Single Field" as I said, when you select one of these you want to get that same Type node again, the code to do this was given in previous post.
 
Well I'm missing something I guess. I've uploaded a simple project with my code inside. If you could take a look at to see what I'm doing wrong, I would greatly appreciate it.

Thanks
 

Attachments

  • XMLLoading.zip
    17 KB · Views: 24
Last edited by a moderator:
You have the selected Type node, it's theTypeNode. Then you start iterating all Type nodes - why?? Just guessing, but don't you think you want to iterate the child nodes of the Type node? That would be like this, (not using that horrible "control arrays" class!) :
VB.NET:
For i As Integer = 0 To theTypeNode.ChildNodes.Count - 1
     Me.Controls("lblName" & i).Text = theTypeNode.ChildNodes(i).Attributes("needs").InnerText
     Me.Controls("txtName" & i).Text = theTypeNode.ChildNodes(i).InnerText
 Next
With the picture a little clearer to what you are doing this code can be made simpler by initially selecting what you want straight away (the Name nodes of a specific Type node):
VB.NET:
Dim xpath As String = String.Format("//Type[@name='{0}']/Name", strAddType)
Dim nameNodes As Xml.XmlNodeList = docXML.DocumentElement.SelectNodes(xpath)
For i As Integer = 0 To nameNodes.Count - 1
    Me.Controls("lblName" & i).Text = nameNodes(i).Attributes("needs").InnerText
    Me.Controls("txtName" & i).Text = nameNodes(i).InnerText
Next
 
You should also look into binding this Xml file to controls. I've attached a project that does this. All that was done was to use the Xsd.exe tool to generate a schema (command "xsd.exe fieldmapping.xml") and "Add Existing Item" to add the generated "fieldmapping.xsd" file to the project. Then it's just about only point and click (it really is just a few mouse clicks to complete it), this was done:
  1. add Dataset from toolbox, select strongly typed in the dialog that presents, this uses the Xml schema you added.
  2. add Combobox and DataGridView controls from toolbox, select DataSource and DisplayMember/DataMember (see what these are set to in the attached project). Also I set Visible=False for the id relation column in DataGridView. (the columns are added automatically based on datasource)
  3. a few lines of code to load data into the dataset in form load with ReadXml method and save with WriteXml method when form closes if there are changes.
To further see how things work: In the project double-click the "fieldmapping.xsd" schema file in solution explorer and it will display as a visual dataset designer window where you can see the tables with their columns and relations, you can see how this relates to your data now. Another time when you are designing a new data application and want to use features like the example just Add New and choose the Dataset template to create a new schema in the visual designer.
 

Attachments

  • BoundXMLLoading.zip
    20.6 KB · Views: 31
All right. I put together a little form that has everything I need input wise. Now I need to figure out how to save the contents of the visible text boxes and enabled labels inside a xml file. I also need to when the form is loaded to read the xml file to populate the fields.
I supplied a xml file that has the general layout I'm looking for. I figured an ini approach was the best but its not really necessary. I didn't see anyway to data bind the form to a xml file with the way I had setup the current form. If there is a viable way I would greatly like to see it since my attempts at data binding have been less then fruitful.

Thank you for your time.
 

Attachments

  • LocatorDialog.zip
    14.2 KB · Views: 24
Last edited:
After some tinkering around I was able to get the file to read the xml and populate to form but I'm still having trouble with the saving part. It makes the file all in one line and isn't dynamic at all.


VB.NET:
    Private Sub readXML()
        ' Class to read the xml docuement
        Dim stream As StreamReader
        Dim reader As XmlTextReader
        Try
            stream = New StreamReader("locsettings.xml")
            reader = New Xml.XmlTextReader(stream)
        Catch ex As FileNotFoundException
            Return 'nothing to load so leave sub
        End Try

        Dim addDoc As New Xml.XmlDocument
        addDoc.Load(reader)

        Dim addCboItems As System.Xml.XmlNodeList
        addCboItems = addDoc.SelectNodes("sections/section")
        Dim addTextItems As System.Xml.XmlNodeList
        addTextItems = addDoc.SelectNodes("sections/section/item")

        Try
            cboAddressing.Text = addCboItems.Item(0).Attributes("name").Value()

            If txtBox0.Visible = True Then
                txtBox0.Text = addTextItems.Item(0).Attributes("value").Value
            End If
            If txtBox1.Visible = True Then
                txtBox1.Text = addTextItems.Item(1).Attributes("value").Value
            End If
            If txtBox2.Visible = True Then
                txtBox2.Text = addTextItems.Item(2).Attributes("value").Value
            End If
            If txtBox3.Visible = True Then
                txtBox3.Text = addTextItems.Item(3).Attributes("value").Value
            End If
            If txtBox4.Visible = True Then
                txtBox4.Text = addTextItems.Item(4).Attributes("value").Value
            End If
            If txtBox5.Visible = True Then
                txtBox5.Text = addTextItems.Item(5).Attributes("value").Value
            End If
            If txtBox6.Visible = True Then
                txtBox6.Text = addTextItems.Item(6).Attributes("value").Value
            End If
            If txtBox7.Visible = True Then
                txtBox7.Text = addTextItems.Item(7).Attributes("value").Value
            End If
            If txtBox8.Visible = True Then
                txtBox8.Text = addTextItems.Item(8).Attributes("value").Value
            End If

            txtFilename.Text = addCboItems.Item(1).FirstChild.Attributes("value").InnerText
        Catch ex As Exception
            MsgBox("The settings file is corrupt", MsgBoxStyle.Critical, "Error!")
        End Try

    End Sub

Now to save it....help! :p

VB.NET:
    Private Sub writeXML()
        Dim writer As New Xml.XmlTextWriter("locsettings.xml", System.Text.Encoding.UTF8)
        writer.WriteStartDocument()
        writer.WriteStartElement("sections")
        writer.WriteStartElement("section")
        If cboAddressing.SelectedIndex <> -1 Then
            writer.WriteAttributeString("name", cboAddressing.SelectedItem.ToString)
        Else
            MsgBox("Unable to save without an addressing type being selected", MsgBoxStyle.Critical, "Error")
        End If

        writer.WriteStartElement("item")
        writer.WriteAttributeString("key", Label0.Text)
        writer.WriteAttributeString("value", txtBox0.Text)
        writer.Close()
    End Sub
 
Back
Top