Creating XML structures

 

XML is a special protocol for describing structured data in a string. XML data is also used to power other applications, such as a CRM system or ERP system, with data.

TCE uses the Microsoft XML type library, which is available in different versions, provided in Windows systems.

The XML structure should be created on the server, so it is only necessary to enable the Typelib switch for this type library. You can reach the Typelib by clicking on the New Type Library button.

In this example, we want to create an XML for all materials.

A well-formed XML looks like this:

<Root xmlns:dt="urn:schemas-microsoft-com:datatypes" Product="Sigma 25">

<Material NumberOf="1" ID="476152" PositionPrice="39.468" Description="Lamp shade Sigma 25 green"/>

<Material NumberOf="1" ID="551212" PositionPrice="2.277" Description="Lamp Halogen 35W"/>

<Material NumberOf="1" ID="561000" PositionPrice="1.311" Description="Lamp base halogen"/>

<Material NumberOf="1" ID="887611" PositionPrice="3.45" Description="Connection cable 2 Meters UK"/>

<Material NumberOf="1" ID="3769" PositionPrice="24.84" Description="Power supply 70W"/>

</Root>

'It consists of exactly one root node, here with the name Root. The root node starts with the tag <Root> and ends with the tag </Root>.

A node can have one or more attributes, such as xmlns:dt and Product. Attributes get a value over an equal sign and the actual value in commas.

There can be one or more nodes between the root node tags that follow the same syntax:

<Material>…</Material>'

A shortened spelling is possible if the node does not have any more child nodes.

<Material />

We now want to generate this XML in TCE.

In the Start class, we create a function called Interface:

 

Public Function Interface() As MSXML2.DOMDocument

  

   Dim DOM As New MSXML2.DOMDocument, oEle As MSXML2.IXMLDOMElement, XMLRoot As MSXML2.IXMLDOMNode

  

   XMLRoot := DOM.appendChild(DOM.createElement("Root"))

   oEle := XMLRoot

   oEle.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes")

  

   XMLRoot.attributes.setNamedItem(DOM.createAttribute("Product")).nodeTypedValue := Product.ObjectClass.Name

  

   Dim Mat As ::Material

  

   For Each Mat In Me.ObjectList(::Material,, True)

      Mat.Interface(DOM, XMLRoot)

   End For

  

End Function DOM

 

In the Microsoft XML library, the object used to describe an XML is called DOMDocument, an object that describes data type conventions is Called IXMLDOMElement, and an object to describe a node in the XML is called XMLDOMNode.

The function first generates an object of type DOMDocument in the variable DOM. This is already done with the help of the New keyword, which is creating an object on first access.

Dim DOM As New MSXML2.DOMDocument, oEle As MSXML2.IXMLDOMElement, XMLRoot As MSXML2.IXMLDOMNode

 

Then the root node root is generated via the DOMDocument object and the reference to this object is stored in the XMLRoot variable.

XMLRoot := DOM.appendChild(DOM.createElement("Root"))

 

Now the (optional) element for data type description is created in the root node:

oEle := XMLRoot

oEle.setAttribute("xmlns:dt", "urn:schemas-microsoft-com:datatypes")

 

Now an attribute product is created in the root node and its value is set:

XMLRoot.attributes.setNamedItem(DOM.createAttribute("Product")).nodeTypedValue := Product.ObjectClass.Name

 

Now all material objects are looped through. For each material object, the function Interface with the transfer of the DOM and the root node is called.

Dim Mat As ::Material

 

For Each Mat In Me.ObjectList(::Material,, True)

   Mat.Interface(DOM, XMLRoot)

End For

 

The DOM object is finally returned as the return parameter of the function.

 

What does the function Interface of the Material class look like, which is called in the loop?

 

Function Interface(ByRef DOM As MSXML2.DOMDocument, ByRef ParentNode As MSXML2.IXMLDOMNode) As Void

   Dim Node As MSXML2.IXMLDOMNode

  

   Node := ParentNode.appendChild(DOM.createElement("Material"))

  

   Node.attributes.setNamedItem(DOM.createAttribute("NumberOf")).nodeTypedValue := NumberOf

   Node.attributes.setNamedItem(DOM.createAttribute("ID")).nodeTypedValue := Me.ObjectClass.Name

   Node.attributes.setNamedItem(DOM.createAttribute("PositionPrice")).nodeTypedValue := [Position Price]

   Node.attributes.setNamedItem(DOM.createAttribute("Description")).nodeTypedValue := Me.ObjectDescription

  

End Function

 

First, a new node is created as a child node of the ParentNode node. The reference to the new node is stored in the variable Node.

Node := ParentNode.appendChild(DOM.createElement("Material"))

 

After that, four attributes are bound to this node:

NumberOf, ID, PositionPrice and Description

 

Now let's try out XML generation:

We create a menu item with the name XML in the main menu to call the interface and in the click event we implement the following code:

 

Private Function Click() As Void

   If Product.ValidChildElements = False Then

      MsgBox(Messages.[Configuration invalid], TCEServer.MsgBoxStyle.Critical,, MainForm.hwnd)

      Return

   End If

  

   Dim DOM As MSXML2.DOMDocument

  

   DOM := Interface

  

   MsgBox(DOM.xml) If DOM <> NoValue

End Function

 

Here we check in the beginning, if there are any invalid elements in our object tree of the product. In that case we stop the output of the XML.

 

You should get the following result: