Link to home
Start Free TrialLog in
Avatar of Jon-Leach
Jon-Leach

asked on

Modifing a XML file with VB.NET

I been looking for a easy way to update a xml that is created by another application with VB.NET. I will be doing this by pulling Data from a SQL DB and putting it the XML file based on PC Host Name. The DB info I am pretty sure I can pull insert, but it's the updating part that got me perplexed. I been surfing the net and have come across a few examples or should I say pieces but nothing that really makes sense to this old pea brain of mine. any help wouold be great.
ASKER CERTIFIED SOLUTION
Avatar of kaufmed
kaufmed
Flag of United States of America image

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
Avatar of Jon-Leach
Jon-Leach

ASKER

Cool thanks I got pulled away yesterday...Let me take a look, I am sure I will have some sort of question :).
Sorry to much on my plate :)

From what I can Tell XDocument lets you drill down further is this right?
Depending on how you write your logic either option will let you drill down as far as you want to go (or even drill up!).
ok I thought I had a handle on it but for some reason I can get it to work.


This is the format in the xml...
<?xml version="1.0" encoding="UTF-8"?>
      <Root>
            <Agent Extn="9500">
                  <CallCenter1>
                        <InstrumentID>946</InstrumentID>                        
                  </CallCenter1>
            </Agent>
      </Root>

This is the output
<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <Agent Extn="9500">
    <CallCenter1>
      <InstrumentID>946</InstrumentID>
    </CallCenter1>
  </Agent>
</Root>

I need to be able to change the InstrumentID  and in the code below I am trying to change it to 5000 for testing purposes to get this part.


I am pretty sure I am close but not putting my fingure on it.

Thanks
System.Xml
Imports System.IO
Public Class AspectXml
    Shared filename As String = "Tapiapp_untouched.xml"

    Sub XmlDocumentExample(ByVal filename As String)
        Dim xdoc As New XmlDocument()

        xdoc.Load(filename) ' Load XML

        'Dim goneNode As XmlNode = xdoc.SelectSingleNode("/library/catalog/book[title='Gone With the Wind']/title")    ' Use XPath to grab specific node
        Dim goneNode As XmlNode = xdoc.SelectSingleNode("/Root/CallCenter1[InstrumentID='946']/CallCenter1")

        If goneNode IsNot Nothing Then
            goneNode.InnerText = "5000"
        End If

        xdoc.Save("output1.xml")
    End Sub
    Sub XDocumentExample(ByVal filename As String)
        Dim xdoc As XDocument = XDocument.Load(filename)

        ' Find the specific node by its title
        Dim goneElement As XElement = _
         xdoc.Descendants("InstrumentID").Where(Function(node As XElement) node.Value = "946").FirstOrDefault()

        If goneElement IsNot Nothing Then
            goneElement.Value = "5000"
        End If

        xdoc.Save("output2.xml")
    End Sub

    Private Sub AspectXml_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        XmlDocumentExample(filename)
        XDocumentExample(filename)
    End Sub
End Class

Open in new window

For the XmlDocument example, you are simply missing one level from the node heirachy. Also, in my example, I was checking that the title element contained the value "Gone With the Wind", but I also wanted to select that title element. The reason the syntax looks the way it does is because at the "book" level, I want to evaluate each book's title; when I find a match, I select that title element. For your purposes, you are wanting to inspect at the "CallCenter1" leve, and when you find an InstrumentID with the value of "946," you want to select that CallCenter1 element. Remove the trailing CallCenter1 reference from the end of the XPath. Try changing line 12 to:

    Dim goneNode As XmlNode = xdoc.SelectSingleNode("/Root/Agent/CallCenter1[InstrumentID='946']/CallCenter1")

and see if you get better results.

XPath is similar to folder paths--each part of the path referers to a sub-node (sub-folder). Whenever you have an indent in XML, you should have another "folder" in your XPath.

For the XDocument example,
I posted the line incorrectly. This is the correct line to match the above description:
Dim goneNode As XmlNode = xdoc.SelectSingleNode("/Root/Agent/CallCenter1[InstrumentID='946']")

Open in new window

Ok I tried "Dim goneNode As XmlNode = xdoc.SelectSingleNode("/Root/Agent/CallCenter1[InstrumentID='946']")" and what i got was that it would remove all the items in the CallCenter1 Section of the xml and leave <CallCenter1>946</CallCenter1>. Something I am doing the above not to work, But anyway I did get this to work just like I wanted.

So thank you for your help.
Sub XDocumentExample(ByVal filename As String)
        Dim xdoc As XDocument = XDocument.Load(filename)

        ' Find the specific node by its title
        Dim goneElement As XElement = _
         xdoc.Descendants("InstrumentID").Where(Function(node As XElement) node.Value = "946").LastOrDefault()
        Dim goneElement1 As XElement = _
         xdoc.Descendants("UserCallBackNum").Where(Function(node As XElement) node.Value = "20946").LastOrDefault()

        If goneElement IsNot Nothing Then
            goneElement.Value = "3000"
        End If

        If goneElement1 IsNot Nothing Then
            goneElement1.Value = "23000"
        End If

        xdoc.Save("output2.xml")
    End Sub

Open in new window

kaufmed was very helpful with my question and showed great patients when answering them.