Login    
 
 
 
 
Text/HTML
  
You are here :: Blogs Saturday, May 19, 2012

Search
Note: This uses the internal blog search engine. The Google search engine is also available at the top of the page.
  
Disclaimer

Please review the site disclaimer before downloading or using content found on this site

  
Categories
  
DEVSHED Blog
As always, I welcome your comments!
Author: Steve Gray Created: 6/17/2010 12:35 PM RssIcon
Code samples against the SYSTEM.XML DOM
By Steve Gray on 4/4/2011 5:45 PM

Here is a simple code example showing how to take a VB Class object and us Xml.Serialization to turn it into an XML string. I had a little trouble finding this code because all the examples wanted to write the XML to disk using a StreamWriter… I needed it in memory as a string

The resulting string looks like  this:

SNAGHTML1b80ab8a

 

Code Snippet
  1. Public Module Module1
  2.  
  3.     Public Class Product
  4.         'this is our simple class of 'product' that we'll create
  5.         Public Property ProductID As String
  6.         Public Property ProductName As String
  7.         Public Property cost As Double
  8.     End Class
  9.     Public Sub Main()
  10.  
  11.         'to make it a little more interesting, we'll serialize an Array of Product
  12.         'declare the array
  13.         Dim oProducts(1) As Product
  14.         'declare the product class
  15.         Dim oProduct As Product
  16.  
  17.         'create the first product
  18.         oProduct = New Product
  19.         oProduct.ProductID = "1"
  20.         oProduct.ProductName = "Hammer"
  21.         oProduct.cost = 5.12
  22.         oProducts(0) = oProduct
  23.  
  24.         'create the second product
  25.         oProduct = New Product
  26.         oProduct.ProductID = "2"
  27.         oProduct.ProductName = "Chisel"
  28.         oProduct.cost = 9.99
  29.         oProducts(1) = oProduct
  30.  
  31.         'Serialize the array to a string
  32.         Dim sw As New IO.StringWriter
  33.         Dim oSerializer As New Xml.Serialization.XmlSerializer(oProducts.GetType)
  34.         oSerializer.Serialize(sw, (oProducts))
  35.         MsgBox(sw.ToString)
  36.  
  37.     End Sub
  38. End Module
By Steve Gray on 3/17/2011 3:53 PM

In the last example we took a simple XML document and deserialized it into a class. This example takes that idea one step further. Our source XML document is a standard ‘order’ with an Order Header and Order Detail sections. The class that we’re going to send it into needs to have a Generic List (of Item) to hold the order details.

Also, in the last example each item in the class was decorated with an <XElement> directive. In this example we’ve remove those and placed a <Serializable> directive at the top of the class.

Also note that the <XmlAttribute> was applied to the OrderNumber property, and it got correctly picked up as an attribute in the XML document

 

Code Snippet
  1. Imports System.Xml.Serialization
  2. Imports Microsoft.VisualBasic
  3.  
  4. Public Class Form2
  5.  
  6.     Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  7.         Try
  8.             ' Declare an object variable of the type to be deserialized.
  9.             Dim i As Order
  10.  
  11.             'Create an instance of the XmlSerializer specifying type and namespace.
  12.             'the 'OrderedItem' class is below
  13.             Dim serializer As New XmlSerializer(GetType(Order))
  14.  
  15.             'open an XmlReader from a string
  16.             'the getXMLDoc function returns an XML document in string format
  17.             Dim reader As System.Xml.XmlReader = System.Xml.XmlReader.Create(New System.IO.StringReader(getXMLDoc))
  18.  
  19.             ' Use the Deserialize method to restore the object's state.
  20.             i = CType(serializer.Deserialize(reader), Order)
  21.  
  22.             ' Write out the properties of the object.
  23.             Console.WriteLine("Item Name: " & i.OrderNumber)
  24.             Console.WriteLine("Item Desc: " & i.CustomerNumber)
  25.  
  26.         Catch ex As Exception
  27.             MsgBox(ex.Message)
  28.         End Try
  29.  
  30.  
  31.     End Sub
  32.  
  33.     Function getXMLDoc() As String
  34.         Dim xElement As XElement
  35.         xElement = <Order OrderNumber="ORD002">
  36.                        <CustomerNumber>CUST001</CustomerNumber>
  37.                        <Items>
  38.                            <Item>
  39.                                <ItemName>Widget</ItemName>
  40.                                <Quantity>1</Quantity>
  41.                                <UnitPrice>9</UnitPrice>
  42.                            </Item>
  43.                            <Item>
  44.                                <ItemName>Widget</ItemName>
  45.                                <Quantity>10</Quantity>
  46.                                <UnitPrice>2.3</UnitPrice>
  47.                            </Item>
  48.                        </Items>
  49.                    </Order>
  50.  
  51.         Return xElement.ToString
  52.  
  53.     End Function
  54. End Class
  55.  
  56. 'This is the class that will be deserialized.
  57. <Serializable()> _
  58. Public Class Order
  59.     <XmlAttribute()> _
  60.     Public OrderNumber As String
  61.  
  62.     Public CustomerNumber As String
  63.     Public Items As List(Of Item)
  64.  
  65. End Class
  66.  
  67. <Serializable()> _
  68. Public Class Item
  69.     Public ItemName As String
  70.     Public Quantity As Integer
  71.     Public UnitPrice As Decimal
  72. End Class
By Steve Gray on 3/17/2011 3:07 PM

I get to see quite a bit of XML, and my path in the past has always been to use LINQ to iterate through the document and read it into a class. Then I’d use the class to do whatever work I need to do.

This code takes advantage of the XmlSerializer.Deserialize method.

To run this code, create a Windows Forms application and drop this code into the form code behind. It is complete and should run unmodified.

Note that the OrderedItem class and the getXMLDoc function both make use of namespaces for two of the elements, so we show how to code this both with and without namespace references.

Code Snippet
  1. Imports System.Xml.Serialization
  2. Imports Microsoft.VisualBasic
  3.  
  4. Public Class Form1
  5.  
  6.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
  7.         Try
  8.             ' Declare an object variable of the type to be deserialized.
  9.             Dim i As OrderedItem
  10.  
  11.             'Create an instance of the XmlSerializer specifying type and namespace.
  12.             'the 'OrderedItem' class is below
  13.             Dim serializer As New XmlSerializer(GetType(OrderedItem))
  14.  
  15.             'open an XmlReader from a string
  16.             'the getXMLDoc function returns an XML document in string format
  17.             Dim reader As System.Xml.XmlReader = System.Xml.XmlReader.Create(New System.IO.StringReader(getXMLDoc))
  18.  
  19.             ' Use the Deserialize method to restore the object's state.
  20.             i = CType(serializer.Deserialize(reader), OrderedItem)
  21.  
  22.             ' Write out the properties of the object.
  23.             Console.WriteLine("Item Name: " & i.ItemName)
  24.             Console.WriteLine("Item Desc: " & i.Description)
  25.  
  26.         Catch ex As Exception
  27.             MsgBox(ex.Message)
  28.         End Try
  29.  
  30.  
  31.     End Sub
  32.  
  33.     Function getXMLDoc() As String
  34.         Dim xElement As XElement
  35.         xElement = <OrderedItem xmlns:money="http://www.devshed.us">
  36.                        <ItemName>Widget</ItemName>
  37.                        <Description>Regular Widget</Description>
  38.                        <Quantity>10</Quantity>
  39.                        <money:UnitPrice>2.3</money:UnitPrice>
  40.                        <money:LineTotal>23</money:LineTotal>
  41.                    </OrderedItem>
  42.  
  43.         Return xElement.ToString
  44.  
  45.     End Function
  46. End Class
  47.  
  48. ' This is the class that will be deserialized.
  49. Public Class OrderedItem
  50.     <XmlElement()> _
  51.     Public ItemName As String
  52.  
  53.     <XmlElement()> _
  54.     Public Description As String
  55.  
  56.     <XmlElement()> _
  57.     Public Quantity As Integer
  58.  
  59.     <XmlElement(Namespace:="http://www.devshed.us")> _
  60.     Public UnitPrice As Decimal
  61.  
  62.     <XmlElement(Namespace:="http://www.devshed.us")> _
  63.     Public LineTotal As Decimal
  64.     ' A custom method used to calculate price per item.
  65.     Public Sub Calculate()
  66.         LineTotal = UnitPrice * Quantity
  67.     End Sub
  68. End Class
By Steve Gray on 10/12/2010 3:14 PM

InsertAfter gave me fits today. This code:

 

    Sub test2()
        Try
            'The reference node is not a child of this node
            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml("<root><doc><node1>1</node1><node3/></doc></root>")

            Dim xnNode1 As XmlNode = xmlDoc.SelectSingleNode("root/doc/node1")
            Dim xnNode2 As XmlNode = xmlDoc.CreateElement("node2")
            xnNode2.InnerXml = "steve"
            xmlDoc.InsertAfter(xnNode2, xnNode1)

            MsgBox(xmlDoc.ToString)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

Always returns ‘The reference node is not a child of this node’. Grrr.

This technique works, though:

    Sub test()
        Try
            'The reference node is not a child of this node
            Dim xmlDoc As New XmlDocument
            xmlDoc.LoadXml("<root><doc><node1>1</node1><node3/></doc></root>")

            Dim xnNode1 As XmlNode = xmlDoc.SelectSingleNode("root/doc/node1")
            Dim xnParent As XmlNode = xnNode1.ParentNode

            Dim xnNode2 As XmlNode = xmlDoc.CreateElement("node2")
            xnNode2.InnerXml = "steve"
            xnParent.InsertAfter(xnNode2, xnNode1)

            MsgBox(xmlDoc.ToString)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

By Steve Gray on 9/13/2010 12:39 PM

Task:

Given this XML document:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <currentProfile>default</currentProfile>
  <profiles>
    <profile name="default">
      <scriptFolder>C:\myScripts</scriptFolder>
    </profile>
    <profile name="special">
      <scriptFolder>C:\specialScripts</scriptFolder>
    </profile>
  </profiles>
</root>

 

We need to get the value of the ‘scriptFolder’ node for the ‘default’ profile.

Here’s the code:

Imports System.Xml
Dim xmldoc As New XmlDocument
xmldoc.Load(Application.StartupPath & "\Profiles.xml")

Dim strQuery As String
strQuery = "root/profiles/profile[@name='default']/scriptFolder"

Dim xnScriptFolder As XmlNode = xmldoc.SelectSingleNode(strQuery)
By Steve Gray on 8/21/2010 11:40 AM

Today’s task has to do with an XML document that has the form:

<OutboundReports>
    <InvoiceNotice>
        <InvoiceNoticeHeader InvoiceDate="20100607" InvoiceType="Invoice" invoiceID="60252726" purpose="PR">
        </InvoiceNoticeHeader>
    </InvoiceNotice>
    <InvoiceNotice>
        <InvoiceNoticeHeader InvoiceDate="20100607" InvoiceType="Invoice" invoiceID="60252727" purpose="PR">
        </InvoiceNoticeHeader>
    </InvoiceNotice>
</OutboundReports>

We need to move the InvoiceDate, InvoiceType, and invoiceID attributes to ‘nodes’, so that our integration program will see them, the current version will not read attributes. Here’s what we want it to look like in the end:

<OutboundReports>
    <InvoiceNotice>
        <InvoiceNoticeHeader InvoiceDate="20100607" InvoiceType="Invoice" invoiceID="60252726" purpose="PR">
            <InvoiceDate>20100607</InvoiceDate>
            <InvoiceType>Invoice</InvoiceType>
            <InvoiceID>60252726</InvoiceID>
        </InvoiceNoticeHeader>
    </InvoiceNotice>
    <InvoiceNotice>
        <InvoiceNoticeHeader InvoiceDate="20100607" InvoiceType="Invoice" invoiceID="60252727" purpose="PR">
            <InvoiceDate>20100607</InvoiceDate>
            <InvoiceType>Invoice</InvoiceType>
            <InvoiceID>60252726</InvoiceID>
        </InvoiceNoticeHeader>
    </InvoiceNotice>
</OutboundReports>

Here’s the code:

            'Load the document
            Dim xmlDoc As New XmlDocument
            xmlDoc.Load(txtSourceFile.Text)
            'loop through the xml document
            Dim elemList As XmlNodeList = xmlDoc.GetElementsByTagName("InvoiceNoticeHeader")
            Dim i As Integer
            Dim MyCultureInfo As System.Globalization.CultureInfo = New System.Globalization.CultureInfo("en-US")
            For i = 0 To elemList.Count - 1
                Dim strInvoiceDate As String = elemList(i).Attributes("InvoiceDate").InnerXml
                Dim dtInvoiceDate As Date = Date.ParseExact(strInvoiceDate, "yyyyMMdd", MyCultureInfo)
                Dim xelemInvoiceDate As XmlElement = xmlDoc.CreateElement("InvoiceDate")
                xelemInvoiceDate.InnerText = strInvoiceDate
                elemList(i).AppendChild(xelemInvoiceDate)
                Dim strInvoiceType As String = elemList(i).Attributes("InvoiceType").InnerXml
                Dim xelemrInvoiceType As XmlElement = xmlDoc.CreateElement("InvoiceType")
                xelemrInvoiceType.InnerText = strInvoiceType
                elemList(i).AppendChild(xelemrInvoiceType)
                Dim strInvoiceID As String = elemList(i).Attributes("invoiceID").InnerXml
                Dim xelemInvoiceID As XmlElement = xmlDoc.CreateElement("InvoiceID")
                xelemInvoiceID.InnerText = strInvoiceID
                elemList(i).AppendChild(xelemInvoiceID)
            Next i
            xmlDoc.Save(Me.txtDestinationFile.Text)
By Steve Gray on 6/17/2010 1:04 PM

The task here is to use the SYSTEM.XML DOM and update a single node in a document. My document looks like this:

<eConnect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <POPReceivingsType>
    <taUpdateCreateVendorRcd>
    </taUpdateCreateVendorRcd>
    <taCreateVendorAddress>
    </taCreateVendorAddress>
    <taPopRcptLineInsert_Items>
      <taPopRcptLineInsert>
        <PONUMBER>PO08/00012</PONUMBER>
        <LOCNCODE>VA-PIEDMONTB</LOCNCODE>
      </taPopRcptLineInsert>
      <taPopRcptLineInsert>
        <PONUMBER>PO08/00012</PONUMBER>
        <LOCNCODE>VA-PIEDMONTA</LOCNCODE>
      </taPopRcptLineInsert>
    </taPopRcptLineInsert_Items>
    <taPopRcptHdrInsert>
      <POPRCTNM>RC08/00028</POPRCTNM>
      <POPTYPE>1</POPTYPE>
      <BACHNUMB>MYBATCH</BACHNUMB>
    </taPopRcptHdrInsert>
  </POPReceivingsType>
</eConnect>

 

Here is a sample of code that will do the deed.

Imports System.Xml
        Dim xmlDoc As New XmlDocument
        xmlDoc.Load(Application.StartupPath & "\xmlfile1.xml")
        Dim xnBatch As XmlNode = xmlDoc.SelectSingleNode("eConnect/POPReceivingsType/taPopRcptHdrInsert/BACHNUMB")
        xnBatch.InnerXml = "NewBatch"
        MsgBox(xmlDoc.InnerXml)
As always, I welcome your comments!
  
 
 
Home | Products | Blogs | Contact Us | Links | God's Plan
Privacy Statement | Terms Of Use
 
Copyright 2011 by Devshed.us