XMLツリーの操作

目次

はじめに

拡張可能マークアップ言語(XML)は、データを人間が読めるテキスト形式のファイルに格納するためのマークアップ言語です。 XML標準は、2つのシステム間でデータを交換するために非常に人気があります。 XMLは、コンピューターアプリケーションと人間の両方によって読み取り可能な テキストファイルを作成する明確な方法を提供します。

XMLファイルはツリー構造に組織化されています。このツリー構造の基本要素をノードと呼びます。 ノードには名前と属性があり、テキスト値を持つことができます。以下の例は、名前が 'Value' で、属性が 'a' と 'b' の2つの属性を持つノードを示しています。 例のノードにはテキスト '10.0' が含まれています。

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

XMLノードは他のノード(子ノードと呼ばれる)を含むこともあります。以下の例は、2つの子ノード 'B' および 'C' を持つ 'A' という名前のノードを示しています。

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

Descriptions of XML elements.


XML技術は通常、次のような用途で使用されます:

  • 構成ファイル
  • アプリケーション間のデータ交換形式
  • 構造化されたデータセット
  • 単純なファイルベースのデータベース

XML形式でデータを読み込むか保存するためには、Xml_LoadFile および Xml_SaveFile の2つのフィルターが必要です。 また、XmlNodeToStringStringToXmlNode の2つの変換も可能です。これらのフィルターは一般的に、シリアルポートやTCP/IPから受信したデータに対して操作を行うために使用されます。

XMLノードへのアクセス

XMLファイルを読み込んだ後は、AccessXmlNode フィルターを使用してすべてのノードプロパティにアクセスできます。

Xml_GetChildNode および Xml_GetAttribute グループのフィルターは、既知の番号または名前を使用してノードの要素に直接アクセスするために使用されます。

指定された条件を使用して要素に対するより複雑なアクセス操作を行うには、XPathクエリを使用した要素の選択 を参照してください。

XMLドキュメントの作成

XMLドキュメントの作成プロセスは、ボトムアップのアプローチで構成されています。まず、ツリー内の最下位ノードを作成する必要があります。その後、そのようなノードをツリー内のより高いレベルのノードに追加でき、そのノードはさらに高いノードに追加できます。親のないノードで、階層の最上位であるノードはルートと呼ばれます。

XMLノードを作成するには、Xml_CreateNode フィルターを使用する必要があります。次に、新しく作成されたノードをルートノードに追加する必要があります。新しいノードにはテキスト値を割り当てることができます。

作成したXMLノードは、Xml_AddChildNodes および Xml_AddChildNodes_OfArray フィルターを使用してツリーに追加できます。新しいノードは子のリストの末尾に追加されます。

また、Xml_SetAttributes フィルターを使用してノードに属性を追加することもできます。

XPathクエリを使用した要素の選択

より複雑なXMLツリーで他の操作を行うには、Xml_SelectNodeValues グループのフィルターを使用できます。ノードのプロパティの変更は、Xml_SetAttributes および Xml_SetNodeValues フィルターを使用して行うこともできます。

XPath条件を使用してフィルターを選択および変更します。XPathは、XMLツリーからサブツリーと属性を選択するためのクエリ言語です。XPathをサポートするすべての選択および設定フィルターは、XPath 1.0仕様をサポートしています。

以下の表は、フィルターXml_SelectMultipleNodesのXPath使用の基本的な例を示しています:

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 Aurora 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.