Solved

Appending an XMLDocument or use a Streamwriter??

Posted on 2006-11-03
7
328 Views
Last Modified: 2008-03-10
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")




0
Comment
Question by:JMO9966
  • 4
  • 3
7 Comments
 
LVL 7

Accepted Solution

by:
Mohamed Zedan earned 300 total points
ID: 17873281
You can do like this :

Private Function GetTag(ByVal xPath As String) As Xml.XmlElement
        Try
            Dim xmlElement As Xml.XmlElement = XmlDoc.SelectSingleNode(xPath)
            Return xmlElement
        Catch ex As Exception
            Console.WriteLine(ex.ToString)
            Return Nothing
        End Try
End Function

Private sub AppendNewChild(dr as System.Data.Datarow)
   dim xmlDoc as xml.XmlDocument    
   xmlDoc = New Xml.XmlDocument
   XmlDoc.Load("VBNET.XML") 'This should be the path to the xml File
   Dim Element as xml.XmlElement = getTag("/JBXML")

 ' this xpath query "/JBXML/JBXMLRequest[@Session='" & SessionID & "']" if you want to select with a parameter  Session Id should contain the sessionid that you want to append to.

''' This is how to get the xml child to append to it the next <WorkCenterAddRq> .
consider Element as newElem1 in your code and substitute it there and you could add how ever you want
''' the dr variable is the new datarow that you want to append to the xml from the table
''' Load your data from it here and do as in your original code like so



''After Loading data....
           If WC <> "" Then
                           Dim newElem3 As XmlElement = xmlDoc.CreateElement("WorkCenterAddRq")
                            Element.AppendChild(newElem3)
                            Dim newElem4 As XmlElement = xmlDoc.CreateElement("WorkCenterAdd")
                            newElem3.AppendChild(newElem4)


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

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

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

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

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

                           End If

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

end sub
0
 

Author Comment

by:JMO9966
ID: 17875290
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



         










0
 
LVL 7

Expert Comment

by:Mohamed Zedan
ID: 17875901
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 :) ...
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:JMO9966
ID: 17886775
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!!
0
 
LVL 7

Expert Comment

by:Mohamed Zedan
ID: 17888310
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 :)
0
 

Author Comment

by:JMO9966
ID: 17893119
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
 
0
 
LVL 7

Expert Comment

by:Mohamed Zedan
ID: 17893131
Your welcome .. if you need anything elese just ask . :)
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now