Link to home
Start Free TrialLog in
Avatar of JMO9966
JMO9966

asked on

Appending an XMLDocument or use a Streamwriter??

Hello,
 
I have a DataTable I loop through and each row will need to have it's own section of "WorkCenterAddRq" in the following XML format.  The following example is one Work Center row from my DataTable.  The second row would need to start another <WorkCenterAddRq> in the location I note below.

Notice at the very bottom, I call the Save method for the XMLDocument.  Once I do this is there a way to append this file with rows 2-999 where noted below or will I need to write all my XML to a string and then send to StreamWriter each time a new record is added??


Thanks,
JMO9966


Here's the XML data generated by the Save method at the end of my code below.  I'd like to append this xml file for each row in my DataTable.

<JBXML>
  <JBXMLRequest Session="13D3BDF9C9A64108A0BF73ED162BF1CC" />
  <WorkCenterAddRq>
    <WorkCenterAdd>
      <ID>WCPress</ID>
    </WorkCenterAdd>
    <DepartmentRef>Machining</DepartmentRef>
    <Capacity>
      <LimitingResources>2</LimitingResources>
      <SchedulingHours>8</SchedulingHours>
      <QueuHours>0</QueuHours>
    </Capacity>
    <BurdenCosts>
      <LaborBurdenRate>10</LaborBurdenRate>
      <MachineBurdenRate>50</MachineBurdenRate>
      <GABurdenRate>15</GABurdenRate>
    </BurdenCosts>
    <LaborCosts>
      <SetupLaborRate>40</SetupLaborRate>
      <RunLaborRate>25</RunLaborRate>
    </LaborCosts>
    </WorkCenterAddRq>
    .......................................................................................WOULD LIKE THE SECOND ROW TO CREATE IT's <WorkCenterAddRq> SECTION BEGINNING HERE.
</JBXML>



I generate my xml by looping through DataTable like this:

For i = 0 To (dsSDK.Tables("tblWork_Centers").Rows.Count - 1)

.......get values


'create XML

If i = 0 Then

                        'Dim newNode As XmlNode = xmlRequestDoc.CreateNode
                        Dim newElem1 As XmlElement = xmlRequestDoc.CreateElement("JBXML")
                        xmlRequestDoc.AppendChild(newElem1)

                        'Dim newElem2 As XmlElement = xmlRequestDoc.CreateElement(strJBXML)
                        'xmlRequestDoc.AppendChild(newElem2)

                        Dim newElem2 As XmlElement = xmlRequestDoc.CreateElement("JBXMLRequest")
                        newElem1.AppendChild(newElem2)
                        'create attribute
                        Dim attrJBXMLRequest As XmlAttribute = xmlRequestDoc.CreateAttribute("Session")
                        attrJBXMLRequest.Value = sessionID
                        'attrJBXMLRequest.Value = strDblQuote & sessionID & strDblQuote
                        'add the new node
                        newElem2.SetAttributeNode(attrJBXMLRequest)
End If


                        If WC <> "" Then
                            Dim newElem3 As XmlElement = xmlRequestDoc.CreateElement("WorkCenterAddRq")
                            newElem1.AppendChild(newElem3)
                            Dim newElem4 As XmlElement = xmlRequestDoc.CreateElement("WorkCenterAdd")
                            newElem3.AppendChild(newElem4)


                            Dim newElem5 As XmlElement = xmlRequestDoc.CreateElement("ID")
                            newElem5.InnerText = WC
                            newElem4.AppendChild(newElem5)

                            If Dept <> "" Then
                                Dim newElem6 As XmlElement = xmlRequestDoc.CreateElement("DepartmentRef")
                                newElem6.InnerText = Dept
                                newElem3.AppendChild(newElem6)
                            End If

                            If LimitResource <> "" Or LimitResource <> "0" Then

                                Dim newElem7 As XmlElement = xmlRequestDoc.CreateElement("Capacity")
                                'newElem7.InnerText = WC
                                newElem3.AppendChild(newElem7)

                                Dim newElem8 As XmlElement = xmlRequestDoc.CreateElement("LimitingResources")
                                newElem8.InnerText = LimitResource.ToString
                                newElem7.AppendChild(newElem8)

                           End If

                                'Save the document to a file and auto-indent the output
                                xmlRequestDoc.Save("VBNET.xml")




ASKER CERTIFIED SOLUTION
Avatar of Mohamed Zedan
Mohamed Zedan
Flag of Canada 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 JMO9966
JMO9966

ASKER

Wow, you made that look easy!

Thanks mohzedan.

Here's what I ended up with:

If row 1 ' generate "header" tags and first row data elements

                       dr = dsSDK.Tables("tblWorkCenters").Rows(i)

                        Element = xmlRequestDoc.CreateElment("JBXML")
                        xmlRequestDoc.AppendChild(Element)

                        Dim newElem2 As XmlElement = xmlRequestDoc.CreateElement("JBXMLRequest")
                        Element.AppendChild(newElem2)
                        'create attribute
                        Dim attrJBXMLRequest As XmlAttribute = xmlRequestDoc.CreateAttribute("Session")
                        attrJBXMLRequest.Value = sessionID
                        newElem2.SetAttributeNode(attrJBXMLRequest)

'add data elements

 If WC <> "" Then
                            Dim newElem3 As XmlElement = xmlRequestDoc.CreateElement("WorkCenterAddRq")
                            newElem1.AppendChild(newElem3)
                            Dim newElem4 As XmlElement = xmlRequestDoc.CreateElement("WorkCenterAdd")
                            newElem3.AppendChild(newElem4)


                            Dim newElem5 As XmlElement = xmlRequestDoc.CreateElement("ID")
                            newElem5.InnerText = WC
                            newElem4.AppendChild(newElem5)

                            If Dept <> "" Then
                                Dim newElem6 As XmlElement = xmlRequestDoc.CreateElement("DepartmentRef")
                                newElem6.InnerText = Dept
                                newElem3.AppendChild(newElem6)
                            End If

                           .......................
                           .......................
                           .......................

                 
End If ' for Row 1



If Row2 or greater Then

       AppendNewChild(dr)

End If




My XML file now looks like I want!  

That getTag function grabs the last element in my xml file named </JBXML> and then when I called Save the second time it knows to add before this tag??  Is that correct?

Thanks Again,
JMO9966



         










The XmlDocument class handles your xml file as a tree ... i.e. handling of closing tags like </JBXM> is automatic
if you append the element in its correct place every thing is fine ... What GetTag function does is execute a xpath query on the xmldocument it's like a database query but for xml it only returns the parent node that you want to append child nodes to ... if yuo have any other questions just ask.. :)

This article offers great explanation on xpath queries and more complicated queries than the one I presented you with. :)
http://www.developer.com/xml/article.php/3383961

And don't forget to ask when you need anything :) ...
Avatar of JMO9966

ASKER

I thought I was done but one last question, I will open another case if needed.

My final output actually has changed slightly.  I need to start the second WorkCenterAddRq in the line noted below.  I now have both </JBXMLRequest> and </JBXML> that will always be the last two lines of my xml document.  Previously, I cited only </JBXML> in our last converstion.

I have this code in the AppendNewChild Sub you recommended.

This code you mentioned works good, but I now have to append to a different location in the xml file:

xmlRequestDoc.Load("VBNET.xml")
Dim Element1 as Xml.XmlElement = GetTag("/JBXML")

Dim newElem3 as XmlElement = xmlRequestDoc.CreateElement("WorkCenterAddRq")
Element1.AppendChild(newElem3)

I'm confused at how appending to tag </JBXML> placed this <WorkCenterAddRq> the line before </JBXML> rather than after but it did work and was what I wanted.


I tried changing AppendNewChild sub to this but it errors on "NullReferenceException" ?? Can't figure out why sub runs fine for one Element ("/JBXML") but not another ("/JBXMLRequest")

xmlRequestDoc.Load("VBNET.xml")
Dim Element1 as Xml.XmlElement = GetTag("/JBXMLRequest")

Dim newElem3 as XmlElement = xmlRequestDoc.CreateElement("WorkCenterAddRq")
Element1.AppendChild(newElem3)                                                                                 - this is the line that gets "NullReferenceException" error





<JBXML>
  <JBXMLRequest Session="13D3BDF9C9A64108A0BF73ED162BF1CC">
  <WorkCenterAddRq>
    <WorkCenterAdd>
      <ID>WCPress</ID>
    </WorkCenterAdd>
    <DepartmentRef>Machining</DepartmentRef>
    <Capacity>
      <LimitingResources>2</LimitingResources>
      <SchedulingHours>8</SchedulingHours>
      <QueuHours>0</QueuHours>
    </Capacity>
    <BurdenCosts>
      <LaborBurdenRate>10</LaborBurdenRate>
      <MachineBurdenRate>50</MachineBurdenRate>
      <GABurdenRate>15</GABurdenRate>
    </BurdenCosts>
    <LaborCosts>
      <SetupLaborRate>40</SetupLaborRate>
      <RunLaborRate>25</RunLaborRate>
    </LaborCosts>
    </WorkCenterAddRq>
    .......................................................................................WOULD LIKE THE SECOND ROW TO CREATE IT's <WorkCenterAddRq> SECTION BEGINNING HERE.
</JBXMLRequest>
</JBXML>



Thanks Mohzedan!!
If you want the <WorkCenterAddRq> tag to be added before </JBXMLRequest> I want you to understand something

my GetTag Function executes something called xPath query this is a language similar in concept to SQL query but is used to query information from an XML file.... the parameter passed to the GetTag function is the Xpath Query ...for example... :

let's say we have the XML file like so:

<MainNode>
       <SubNode1 id="0"/>
       <SubNode1 id="1"/>
       <SubNode2>
               <SubNode21/>
       </SubNode2>
</MainNode>

the xpath query to get all the "subnode1" tags is like this = "/MainNode/SubNode1"
the xpath query to get the "subnode2" tag is like this = "/MainNode/SubNode2"
the xpath query to get the "subnode21" tag is like this = "/MainNode/SubNode2/SubNode21"
the xpath query to get the "subnode1" tag with ID attribute ="1" is like this = "/MainNode/SubNode1[@id="1"]"

After that these xpath queries return to you either a single Element or a nodelist (element array)
when you want to add a child element to the end of the Current element child nodes you use
Element1.AppendChild()

if you want to add a child element to the beginning of the selected element child nodes you use
Element1.PrependChild()


in your case you would use this xpath query (I mentioned it as a comment in the first post :) ) ....

"/JBXML/JBXMLRequest[@Session='" & SessionID & "']"

Dim Element1 as Xml.XmlElement = GetTag("/JBXML/JBXMLRequest[@Session='" & SessionID & "']")
Dim newElem3 as XmlElement = xmlRequestDoc.CreateElement("WorkCenterAddRq")
Element1.AppendChild(newElem3)

you have to supply the sessionId because I guess that your xml file will grow and include more sessions than this one
Anything vague just ask and I will answer your every question :) ... I love to help :)
Avatar of JMO9966

ASKER

Thank You!!!

Most of my programs will only have one sessionID so I used this, but I will keep your parameter in mind for multiple session ID's also.

GetTag("/JBXML/JBXMLRequest") and it did exactly what I wanted.

You gave me the most well explained answers I've ever received on this site and that's saying a lot!

Thanks Mohzedan,
JMO9966
 
Your welcome .. if you need anything elese just ask . :)