You are here: Start » Programming Tips » Working with XML Trees

Working with XML Trees

Table of contents

Introduction

Extensible Markup Language (XML) is a markup language used for storing data in human readable text-format files. XML standard is very popular in exchanging data between two systems. XML provides a clear way to create text files which can be readable both by a computer application and a human.

An XML file is organized into a tree structure. The basic element of this tree structure is called a node. A node has a name, attributes and can have a text value. The example below shows a node with the name 'Value' and with two attributes 'a', 'b'. The example node contains text '10.0'.

 <Value a="1.0" b="2.0">10.0</Value>

An XML node can also contain other nodes which are called children. The example below shows a node named 'A' with two children: 'B' and 'C'.

 <A>
  <B />
  <C />
 </A>

Descriptions of XML elements.


The XML technology is commonly used for:

  • Configuration files
  • Data exchange format between applications
  • Structured data sets
  • Simple file-based databases

To load or store data in the XML format, two filters are necessary: Xml_LoadFile and Xml_SaveFile. Also two conversions are possible: XmlNodeToString and StringToXmlNode. These filters are commonly used to perform operations on data received from different sources like Serial Port or TCP/IP.

Accessing XML Nodes

After loading an XML file all node properties can be accessed with AccessXmlNode filter.

Xml_GetChildNode and filters from group Xml_GetAttribute are used to access directly a node's element using its known number or name.

To perform more complex access operations on elements using specified criteria, please read: Selecting Elements Using XPath Query.

Creating an XML Document

The process of creating XML documents is organized in a bottom-up approach. At the beginning, the lowest nodes in the tree must be created. Then, such nodes can be added to a node at a higher level in the tree and that node can be added to some yet higher node and so on. The node without a parent which is the highest level in hierarchy is called root.

To create an XML node Xml_CreateNode filter should be used. Then, the newly created node should be added to the root node. The new node can have text value assigned.

Created XML nodes should be added to the tree using Xml_AddChildNodes and Xml_AddChildNodes_OfArray filters. New nodes will be added to the end of the list of children.

Also attributes can be added to a node using Xml_SetAttributes filter.

Selecting Elements Using XPath Query

To perform other operations on more complex XML trees filters from group Xml_SelectNodeValues can be used. Modification of the node's properties can be also done by using Xml_SetAttributes and Xml_SetNodeValues filters.

Selecting and altering filters is done using XPath criteria. XPath is a query language used to selecting sub-trees and attributes from an XML tree. All selecting and setting filters that are using XPath support the XPath 1.0 Specification.

The table below shows basic examples of XPath usage of filter Xml_SelectMultipleNodes:

Example XPath Description
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>

/root Selecting all nodes of type 'root' that are at the first level of the tree.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
<result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>

</root>
/root/result[2] Selecting the second child of 'root' node which is of type 'result'.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root/result/value Selecting all children of type 'value' of parent nodes '/root/result' of a specified XML node.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root/result[2]/value[2] Selecting specified second child of type 'root' and the second child of 'result'.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//value Selecting all value nodes regardless of their position in the XML tree.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//*[@status] Selecting all nodes which have 'status' attribute name.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//*[@status='fail'] Selecting all nodes which have 'status' of value 'fail'.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
<result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>

</root>
//*[starts-with(name(),'res') and (@time > 200)] Selecting all nodes with names starting with 'res' and having attribute 'time' greater than '200'.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//*[contains(text(),'10')] Selecting all nodes whose text (value) contains '10'.

Notice: All indexes are counted starting from [1].

The table below shows basic examples of XPath usage of Xml_SelectMultipleNodeValues_AsStrings filter:

Example XPath Description
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root[1]/result[2]/value[2] Selecting value from a specified node.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail"> </value>
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root[1]/result[1]/value Get all node values from a specific node. Notice that empty XML nodes empty contains a default type value.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail"></value>
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root[1]/result/value[@type='length'] Get values of all nodes with attribute length.
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail"></value>
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
/root[1]/result/value[@type='length']|/root[1]/result/value[@type='score'] Get values of all nodes with attribute length and nodes with score attribute.

The table below shows basic examples of XPath usage of Xml_SelectMultipleAttributes_AsStrings filter:

Example XPath Description
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//*/@type Selecting all attributes named 'type' .
<?xml version="1.0" ?>
<root>
 <result time="200">
  <value type="length">33.3</value>
  <value type="score">1.00</value>
  <value status="fail" />
 </result>
 <result time="250">
  <value type="length">10.6</value>
  <value type="score">0.30</value>
  <value status="pass" />
 </result>
</root>
//*[./*[@status='fail']]/@time Selecting all attributes 'time' of nodes whose one of the children has status fail.

Common Practices (tips)

  • Creating an XML tree by appending new nodes is not always necessary. If the tree structure is constant, the whole XML tree can be stored in a Global Parameter and when it is necessary new values of attributes or node text can be set using Xml_SetAttributes and Xml_SetNodeValues filters.
  • XML files are very handy to store program settings.
  • Most of Adaptive Vision Studio objects can be serialized to text and stored in an XML file.
  • XmlNodeToString filter can be used to send XML via TCP/IP or Serial Port.
Previous: Understanding OrNil Filter Variants Next: Technical Issues