If node exists then?

vbMarkO

Well-known member
Joined
Aug 19, 2005
Messages
157
OK, here is what I am doing and the code I am using..


I have a simple text file that looks like this
Code:
74422 Boynton
73011 Bradley
74423 Braggs
74632 Braman
73012 Bray
74010 Bristow
74011 Broken Arrow
74012 Broken Arrow
74013 Broken Arrow
74014 Broken Arrow
74728 Broken Bow
74530 Bromide
73834 Buffalo
74931 Bunch
74633 Burbank
73722 Burlington
73430 Burneyville
73624 Burns Flat
73625 Butler
74831 Byars
73527 Cache
74729 Caddo
74730 Calera
73014 Calumet
74531 Calvin
73835 Camargo
74932 Cameron
74425 Canadian

These are towns and zipcodes.....

I am putting taking from the textfile and putting them into an xmlFile as seen by the code below
However there is a problem.....

When I get to the towns where there are multiple zipcodes... such as Broken Arrow above...

Its creating an element for Each Broken Arrow zipCode

My xml structure I am wanting should be this

Code:
<?xml version="1.0" standalone="yes"?>
<CitiesZipOK>
        <Bristow>
                <Zip>74010</Zip>
        </Bristow>
	<Broken_Arrow>
                <Zip>74011</Zip>
                <Zip>74012</Zip>
                <Zip>74013</Zip>
                <Zip>74013</Zip>
        </Broken_Arrow>
        <Broken_Bow>
                 <Zip>74728</Zip>
        </Broken_Bow>
</CitiesZipOK>


INstead I am getting multiple Broken_Arrow elements....
How can I change my code to make this work?
Seems I need to create the city element but somehow check if it exisits if so then add all the zips associated with that CIty in one element as I did with Broken_Arrow elelment....




Code:
 Dim reader As New StreamReader(myFile)
        Dim xmlDoc As New XmlDocument
        Dim cityNode As XmlNode = Nothing
        Dim node As XmlNode
        Dim line As String


        xmlDoc.Load(xmlFile)
        line = reader.ReadLine()

        Do While (line IsNot Nothing)

            Dim myCity As String = line.Substring(6)  Returns City or Town
            Dim myArr() As String = Split(line, " ")
            Dim myZip As String = myArr(0)  line.Substring(0, line.IndexOf(" "))  Returns ZipCode
            myCity = myCity.Replace(" ", "_")
            cityNode = xmlDoc.CreateElement(myCity)
            node = xmlDoc.CreateElement("Zip")
            node.InnerText = myZip

            cityNode.AppendChild(node)
            xmlDoc.DocumentElement.AppendChild(cityNode)


            line = reader.ReadLine()
        Loop

        reader.Close()
        xmlDoc.Save(xmlFile)


vbMarkO
 
Im sorry but the question begs to be asked here, did you actually try and do it yourself? Its not that Id mind helping, but the solution to this is practically identical to the question about updating a node which we helped you with in davearias thread. This is the logic behind what you need todo..

1. loop through text file
2. if city node exists add zip node to it
3. else add city node
4. add zip node to new city mode

The code you posted goes straight from 1 to 3 without even attempting 2. As you will see if you look back at that update question, this is a very similar problem. If you have trouble implementing then dont hesitate to ask questions about your code.
 
Yes I am trying...

In fact I have already resolved it...

But thank you for replying ... you beat me in posting it resolved...


vbMarkO
 
Ok I thought this was resolved but upon close examination of the xmlFile it is definately not resolved....


I will post the code after I show the results of what I am getting....

It is giving me this
Code:
  <City name="Achille">
    <Zip>74720</Zip>
  </City>
  <City name="Ada">  Note this attribute and the next one in line
    <Zip>74820</Zip>
  </City>
  <City name="Ada">
    <Zip>74821</Zip>  note the duplicates
    <Zip>74821</Zip>
  </City>
  <City name="Adair">
    <Zip>74330</Zip>
  </City>

It should have been this
Code:
  <City name="Achille">
    <Zip>74720</Zip>
  </City>
  <City name="Ada">
    <Zip>74820</Zip>
    <Zip>74821</Zip> 
  </City>
  <City name="Adair">
    <Zip>74330</Zip>
  </City>


Now here is my code.... I am sure I am overlooking the obvious but if you dont mind... could you point it out to me? :)


Code:
   Dim reader As New StreamReader(myFile)
        Dim xmlDoc As New XmlDocument
        Dim cityNode As XmlNode = Nothing
        Dim node As XmlNode
        Dim line As String
        Dim myName As XmlAttribute


        xmlDoc.Load(xmlFile)
        line = reader.ReadLine()

        Do While (line IsNot Nothing)

            Dim myCity As String = line.Substring(6)  Returns City or Town
            Dim myArr() As String = Split(line, " ")
            Dim myZip As String = myArr(0)  Returns ZipCode
            myCity = myCity.Replace(" ", "_")

            If (line.EndsWith(myCity)) Then

                cityNode = xmlDoc.CreateElement("City")
                myName = xmlDoc.CreateAttribute("name")
                myName.InnerText = myCity

                cityNode.Attributes.Append(myName)
                xmlDoc.DocumentElement.AppendChild(cityNode)

                ElseIf ((line.Length > 0) AndAlso (cityNode IsNot Nothing)) Then


                For Each myNode As XmlNode In xmlDoc.DocumentElement.ChildNodes
                    If myNode.Attributes("name").InnerText = myCity Then
                        node = xmlDoc.CreateElement("Zip")
                        node.InnerText = myZip

                        cityNode.AppendChild(node)
                    End If
                Next







            End If



            line = reader.ReadLine()
        Loop

        reader.Close()
        xmlDoc.Save(xmlFile)


I am still giving a try to see if I can figure this out but I descided after the many attempts to seek some direction....myBad for thinking it was resolved...

vbMarkO
 
Well firstly you are appending the cityNode to the document before evening checking if it already exists. This should be done after the loop, and only if the node wasnt already found.

Secondly inside the for loop you are attaching the Zip node to the cityNode element, when in fact you should be adding it to myNode because as your loop just checked myNode is the node for that city.
 
Ok, I am definately not gettng it.....

I have went back to the other code from the other thread as you mentioned it was nearly the same thing ....

The problem I am having is figuring out how to check if the City tag or node already exists...

Do you think you could give me a hint as to how this is done?


vbMarkO
 
You pretty much have the code you need, just in the wrong order. You say your struggling to find out if the city node is present yet your code already does it.
Code:
For Each myNode As XmlNode In xmlDoc.DocumentElement.ChildNodes
    If myNode.Attributes("name").InnerText = myCity Then
         here its found
    End If
Next
This code checks for the city node, if your code reaches the here its found comment, then myNode is the city node you are looking for. From there simply add the zip node to it, you can also store a boolean as true so that when you exit the loop you know it was found. After the loop you check that boolean state, if its true your jobs done, if its not you need to add the city node (as it wasnt found) and then add the zip node to that new city node. I could write the full code out for you, but I fear if I did you wouldnt learn much from it.
 
I guess this one is not working for me...

I appreciate the input However dont agree with the teaching method... while I dont feel it is any bodies responcibility to write code for us that are not as experienced.... I dont agree that trying without showing is the right method for teaching or learning

As a Genreal Contractor for over 23 years I have trained many Sub contractors how to work in the areas we specialize in and I always taught them by example not trial and error...

This one no matter how simple it might be to you and others ... its just not happening for me...

Please note, my above comments are not meant in a scolding manner as sometimes text can come accross that way....

I have learned alot from this forum but most of it has been by example allowing me to disect the code.....

So if its not to much or not out of line.... I would humbly appreciate more of an example as to what you are trying to get accross to me and simply forgive my ignorance

:)

vbMarkO
 
YaHooooooooo I got it.....

I am going to post the code I put together....

I know its not what you were trying to tell me... b ut since you didnt give me an example I descided to take a different approach

Hey you know the mother of invention approach :)

Anyway I descided to use 2 ArrayList to get it done...

Here is the code its crude.... but it worked... I am however more than open to see what you had in mine as I am sure it is better because of your experience but just the same we are dancing for joy over here and doing the Walter Brennon dance :)



Here it is!

Code:
 Dim reader As New StreamReader(myFile)
        Dim xmlDoc As New XmlDocument
        Dim cityNode As XmlNode = Nothing
        Dim node As XmlNode
        Dim line As String


        Dim myName As XmlAttribute


        xmlDoc.Load(xmlFile)
        line = reader.ReadLine()




        Dim cityArr As New ArrayList
        Dim myZip As New ArrayList
         Dim zipArr As New ArrayList
        Do While (line IsNot Nothing)

            Dim myCity As String = line.Substring(6)  Returns City or Town
            Dim myArr() As String = Split(line, " ")
            myArr(0)  line.Substring(0, line.IndexOf(" "))  Returns ZipCode
            myCity = myCity.Replace(" ", "_")


            If (line.EndsWith(myCity)) Then


                If cityArr.Contains(myCity) = False Then
                    cityArr.Add(myCity)

                End If
                If myZip.Contains(line) = False Then
                    myZip.Add(line)
                End If


            End If

            line = reader.ReadLine()
        Loop

        reader.Close()
         Create City node and its attribute containingname of City or town

        For i As Integer = 0 To cityArr.Count - 1
            cityNode = xmlDoc.CreateElement("City")
            myName = xmlDoc.CreateAttribute("name")
            myName.InnerText = cityArr(i)

            cityNode.Attributes.Append(myName)
            xmlDoc.DocumentElement.AppendChild(cityNode)
            
        Next
         Now add zip nodes with zipcodes
        For x As Integer = 0 To myZip.Count - 1
            Dim myString As String = myZip(x)
            For Each myNode As XmlNode In xmlDoc.DocumentElement.ChildNodes
                If myNode.Attributes("name").InnerText = myString.Substring(6) Then
                    node = xmlDoc.CreateElement("Zip")
                    node.InnerText = myString.Substring(0, myString.IndexOf(" "))

                    myNode.AppendChild(node)

                End If
            Next
        Next
        xmlDoc.Save(xmlFile)


That got it done.....


vbMarkO
 
As far as I can tell your code will read a file and work as you intend it. Whilst it does somewhat limit you in terms of adding more items, if that isnt a requirement I guess it doesnt matter. Since youve obviously had a go heres the way I would have done it (I just got up, hope it makes sense).
Code:
        Dim reader As New StreamReader(myFile)
        Dim xmlDoc As New XmlDocument
        Dim line As String

        xmlDoc.Load(xmlFile)
        line = reader.ReadLine()

        Do While (line IsNot Nothing)

             Ill go ahead and assume these lines of code successfully extract a city and a zip code
            Dim myCity As String = line.Substring(6)  Returns City or Town
            Dim myArr() As String = Split(line, " ")
            Dim myZip As String = myArr(0)  Returns ZipCode
            Dim foundCity As Boolean = False

             loop through nodes
            For Each myNode As XmlNode In xmlDoc.DocumentElement.ChildNodes
                
                 check if its the right city node
                If myNode.Attributes("name").InnerText = myCity Then
                     
                     since we have the right node add the zip node
                    Dim zipNode As XmlElement = xmlDoc.CreateElement("Zip")
                    zipNode.InnerText = myZip
                    myNode.AppendChild(zipNode)  add the zip to that citys node
                    foundCity = True  store the fact the city was found
                    Exit For  some say this is bad practice, but its the simplest way to prevent loop finishing
                    
                End If
                
            Next

             if the city wasnt found
            If (Not foundCity) Then
                
                 create the city node
                Dim cityNode As XmlElement = xmlDoc.CreateElement("City")  create node
                Dim nameAttr As XmlAttribute = xmlDoc.CreateAttribute("name")  create attribute
                nameAttr.InnerText = myCity  populate attribute
                cityNode.Attributes.Append(nameAttr)  add attribute
                 create the zip node
                Dim zipNode As XmlElement = xmlDoc.CreateElement("Zip")
                zipNode.InnerText = myZip
                cityNode.AppendChild(zipNode)  add the zip to that citys node
                 add node to document
                xmlDoc.DocumentElement.AppendChild(cityNode)  add city node to doc
                
            End If

            line = reader.ReadLine()
        Loop

        reader.Close()
        xmlDoc.Save(xmlFile)
 
Yes this worked too...

I am kicking myself because you just dont know how close I was to having that... and I see where I messed up.....

Thank you. I will study them both and break them down.... I like yours ofcourse as it is cleaner.....

Though the results are the same, I preffer cleaner code.....

Thank you again for the great insight.... I learn so much from example.... though I always try to get it myself first......


vbMarkO
 
Back
Top