You can store various test data in XML files. For example, an XML file can store the name of a control, over which TestComplete will simulate user actions, and input values. You can also use XML files to store data between test runs.
Approaches to Working With XML Files in TestComplete
To work with XML files in TestComplete, you can use the following objects:
-
XML DOM objects. You can use these objects to work with any XML file. Working with these objects requires more efforts and knowledge of XML DOM. However, we suggest that you use these objects to work with XML files.
-
The TestComplete
Storages
object. You use the methods and properties of this object to write data to and read it from XML files. However, this object works only with XML files created with theStorage.XML
method (such files have a specific format, they include sections, subsections and options). For more information on this, see Section Object. If you try to open an XML file that has another format by using theStorage.XML
method, an error will occur.
Using XML DOM Objects
To work with arbitrary XML files, you can use XML DOM objects. These objects provide a COM interface to each element and attribute of the XML document. All interactions with XML files are done through Microsoft XML Core Services (MSXML):
-
To start working with XML files, create a COM object:
JavaScript
// If you have MSXML 4:
var Doc = getActiveXObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
var Doc = getActiveXObject("Msxml2.DOMDocument.6.0");JScript
// If you have MSXML 4:
var Doc = Sys.OleObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
var Doc = Sys.OleObject("Msxml2.DOMDocument.6.0");Python
# If you have MSXML 4: Doc = Sys.OleObject["Msxml2.DOMDocument.4.0"] # If you have MSXML 6: Doc = Sys.OleObject["Msxml2.DOMDocument.6.0"]
VBScript
' If you have MSXML 4:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.4.0")
' If you have MSXML 6:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.6.0")DelphiScript
var
Doc;
begin
...
// If you have MSXML 4:
Doc := Sys.OleObject('Msxml2.DOMDocument.4.0');
// If you have MSXML 6:
Doc := Sys.OleObject('Msxml2.DOMDocument.6.0');C++Script, C#Script
// If you have MSXML 4:
var Doc = Sys["OleObject"]("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
var Doc = Sys["OleObject"]("Msxml2.DOMDocument.6.0"); -
Load data from a file you want to process:
JavaScript, JScript
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
Python
Doc.load("C:\\Data.xml")
VBScript
Call Doc.load("../../../../_topics/scripting/working-with-files/C:\Data.xml")
DelphiScript
Doc.load('C:\Data.xml');
C++Script, C#Script
Doc["../../../../_topics/scripting/working-with-files/load"]("C:\\Data.xml");
Note: When loading XML files with a document type declaration, you may face the "DTD is prohibited" error. If it happens, modify your script and add a string that will disable the ProhibitDTD property of the created COM object:
JavaScript, JScript
Doc.setProperty("ProhibitDTD", false);
Python
Doc.setProperty("ProhibitDTD",False)
VBScript
Call Doc.setProperty("ProhibitDTD", False)
DelphiScript
Doc.setProperty('ProhibitDTD', False);
C++Script, C#Script
Doc["setProperty"]("ProhibitDTD", false);
-
After the file is loaded, you can start processing it in a way you need. You can find examples of some of the most common tasks below.
Information on XML DOM Objects
To find more information on XPath expressions and XML DOM objects, as well as on their methods and properties, see the corresponding documentation in the MSDN library:
Examples
In this topic, all examples work with the Data.xml file located in the root folder of the C drive. The file should contain the following code:
Data.xml
<?xml version="1.0"?>
<controls>
<control id="1">
<type>TextEdit</type>
<name>Text1</name>
<value>My string</value>
</control>
<control id="2">
<type>Button</type>
<name>Btn1</name>
<value>OK</value>
</control>
<control id="3">
<type>TextEdit</type>
<name>Text2</name>
<value>My string</value>
</control>
<control xmlns="CheckBoxes">
<type>CheckBox</type>
<name>CheckBox1</name>
<value>True</value>
</control>
<control xmlns="Button2">
<type>Button</type>
<name>Btn2</name>
<value>Cancel</value>
</control>
</controls>
This file has the root node "controls" that has five subnodes. Each subnode has three nodes: type, name and value. The last two nodes also have a namespace specified.
Example 1: Opening XML Files
The following code shows how to open an XML file and parse it.
JavaScript
function TestXMLDOM()
{
var Doc, Node, s;
// Create a COM object
// If you have MSXML 4:
Doc = getActiveXObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = getActiveXObject("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
// Obtain the node
Node = Doc.documentElement;
// Process the node
ProcessNode(Node);
}
function ProcessNode(ANode)
{
var FID, Attrs, i, Attr, ChildNodes;
// Create a log folder for each node and activate the folder
FID = Log.CreateFolder(ANode.nodeName);
Log.PushLogFolder(FID);
// If the node value is not null, output it
if( aqObject.GetVarType(ANode.nodeValue) != 1)
Log.Message("Value: " + aqConvert.VarToStr(ANode.nodeValue));
// Process the node's attributes
// Exclude helper nodes from processing
if( ANode.nodeName.charAt(0) != "\#")
{
// Obtain the attribute collection and
// output the attributes to the log
Attrs = ANode.attributes;
for(i = 0; i < Attrs.length; i++)
{
Attr = Attrs.item(i);
Log.Message("Attr " + Attr.nodeName + ": " + Attr.nodeValue);
}
}
// Obtain the collection of child nodes
ChildNodes = ANode.childNodes;
// Processes each node of the collection
for(i = 0; i < ChildNodes.length; i++)
ProcessNode(ChildNodes.item(i));
// Close the log folder
Log.PopLogFolder();
}
JScript
function TestXMLDOM()
{
var Doc, Node, s;
// Create a COM object
// If you have MSXML 4:
Doc = Sys.OleObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys.OleObject("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
// Obtain the node
Node = Doc.documentElement;
// Process the node
ProcessNode(Node);
}
function ProcessNode(ANode)
{
var FID, Attrs, i, Attr, ChildNodes;
// Create a log folder for each node and activate the folder
FID = Log.CreateFolder(ANode.nodeName);
Log.PushLogFolder(FID);
// If the node value is not null, output it
if( aqObject.GetVarType(ANode.nodeValue) != 1)
Log.Message("Value: " + aqConvert.VarToStr(ANode.nodeValue));
// Process the node's attributes
// Exclude helper nodes from processing
if( ANode.nodeName.charAt(0) != "\#")
{
// Obtain the attribute collection and
// output the attributes to the log
Attrs = ANode.attributes;
for(i = 0; i < Attrs.length; i++)
{
Attr = Attrs.item(i);
Log.Message("Attr " + Attr.nodeName + ": " + Attr.nodeValue);
}
}
// Obtain the collection of child nodes
ChildNodes = ANode.childNodes;
// Processes each node of the collection
for(i = 0; i < ChildNodes.length; i++)
ProcessNode(ChildNodes.item(i));
// Close the log folder
Log.PopLogFolder();
}
Python
def TestXMLDOM():
# Create a COM object
# If you have MSXML 4:
Doc = Sys.OleObject["Msxml2.DOMDocument.4.0"]
# If you have MSXML 6:
Doc = Sys.OleObject["Msxml2.DOMDocument.6.0"]
Doc.async = False
# Load data from a file
# We use the file created earlier
Doc.load("C:\\Data.xml")
# Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode != 0:
s = "Reason:\t" + Doc.parseError.reason + "\n" + "Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" + "Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" + "Source:\t" + Doc.parseError.srcText
# Post an error to the log and exit
Log.Error("Cannot parse the document.", s)
return
# Obtain the node
Node = Doc.documentElement
# Process the node
ProcessNode(Node)
def ProcessNode(ANode):
# Create a log folder for each node and activate the folder
FID = Log.CreateFolder(ANode.nodeName)
Log.PushLogFolder(FID)
# If the node value is not null, output it
if aqObject.GetVarType(ANode.nodeValue) != 0 and aqObject.GetVarType(ANode.nodeValue) != 1:
Log.Message("Value: " + aqConvert.VarToStr(ANode.nodeValue))
# Process the node's attributes
# Exclude helper nodes from processing
if ANode.nodeName[0] != "#":
# Obtain the attribute collection and
# output the attributes to the log
Attrs = ANode.attributes
for i in range(Attrs.length):
Attr = Attrs.item[i]
Log.Message("Attr " + Attr.nodeName + ": " + Attr.nodeValue)
# Obtain the collection of child nodes
ChildNodes = ANode.childNodes
# Processes each node of the collection
for i in range(ChildNodes.length):
ProcessNode(ChildNodes.item[i])
# Close the log folder
Log.PopLogFolder()
VBScript
Sub TestXMLDOM
' Create a COM object
' If you have MSXML 4:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.4.0")
' If you have MSXML 6:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.6.0")
Doc.async = False
' Load data from a file
' We use the file created earlier
Call Doc.load("../../../../_topics/scripting/working-with-files/C:\Data.xml")
' Report an error, if, for instance, the markup or file structure is invalid
If Doc.parseError.errorCode <> 0 Then
s = "Reason:" + Chr(9) + Doc.parseError.reason + Chr(13) + Chr(10) + _
"Line:" + Chr(9) + CStr(Doc.parseError.line) + Chr(13) + Chr(10) + _
"Pos:" + Chr(9) + CStr(Doc.parseError.linePos) + Chr(13) + Chr(10) + _
"Source:" + Chr(9) + Doc.parseError.srcText
' Post an error to the log and exit
Call Log.Error("Cannot parse the document.", s)
Exit Sub
End If
' Obtain the node
Set Node = Doc.documentElement
' Process the node
Call ProcessNode(Node)
End Sub
Sub ProcessNode(ANode)
' Create a log folder for each node and activate the folder
FID = Log.CreateFolder(ANode.nodeName)
Log.PushLogFolder FID
' If the node value is not null, output it
If aqObject.GetVarType(ANode.nodeValue) <> 1 Then
Log.Message "Value: " + ANode.nodeValue
End If
' Process the node's attributes
If Left(ANode.nodeName, 1) <> "#" Then ' Exclude helper nodes from processing
' Obtain the attribute collection and
' output the attributes to the log
Set Attrs = ANode.attributes
For i = 0 To Attrs.length - 1
Set Attr = Attrs.item(i)
Log.Message "Attr " + Attr.nodeName + ": " + Attr.nodeValue
Next
End If
' Obtain the collection of child nodes
Set ChildNodes = ANode.childNodes
' Processes each node of the collection
For i = 0 to ChildNodes.length - 1
ProcessNode ChildNodes.item(i)
Next
' Close the log folder
Log.PopLogFolder
End Sub
DelphiScript
procedure ProcessNode(ANode : OleVariant); forward;
procedure TestXMLDOM;
var
Doc, Node, s : OleVariant;
begin
// Create a COM object
// If you have MSXML 4:
Doc := Sys.OleObject('Msxml2.DOMDocument.4.0');
// If you have MSXML 6:
Doc := Sys.OleObject('Msxml2.DOMDocument.6.0');
Doc.async := False;
// Load data from a file
// We use the file created earlier
Doc.load('C:\Data.xml');
// Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode <> 0 then
begin
s := 'Reason:' + #9 + Doc.parseError.reason + #13#10 +
'Line:' + #9 + aqConvert.VarToStr(Doc.parseError.line) + #13#10 +
'Pos:' + #9 + aqConvert.VarToStr(Doc.parseError.linePos) + #13#10 +
'Source:' + #9 + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error('Cannot parse the document.', s);
Exit;
end;
// Obtain the node
Node := Doc.documentElement;
// Process the node
ProcessNode(Node);
end;
procedure ProcessNode(ANode : OleVariant);
var
FID, s, Attrs, Attr, i, ChildNodes : OleVariant;
begin
// Create a log folder for each node and activate the folder
FID := Log.CreateFolder(ANode.nodeName);
Log.PushLogFolder(FID);
// If the node value is not nil, output it
if aqObject.GetVarType(ANode.nodeValue) <> 1 then
Log.Message('Value: ' + aqConvert.VarToStr(ANode.nodeValue));
// Process the node's attributes
s := Copy(ANode.nodeName, 1, 1);
if s <> '#' then // Exclude helper nodes from processing
begin
// Obtain the attribute collection and
// output the attributes to the log
Attrs := ANode.attributes;
for i := 0 to Attrs.length - 1 do
begin
Attr := Attrs.item[i];
Log.Message('Attr ' + Attr.nodeName + ': ' + Attr.nodeValue);
end;
end;
// Obtain the collection of child nodes
ChildNodes := ANode.childNodes;
// Processes each node of the collection
for i := 0 to ChildNodes.length - 1 do
ProcessNode(ChildNodes.item[i]);
// Close the log folder
Log.PopLogFolder();
end;
C++Script, C#Script
function TestXMLDOM()
{
var Doc, Node, s;
// Create a COM object
// If you have MSXML 4:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.6.0");
Doc["async"] = false;
// Load data from a file
// We use the file created earlier
Doc["../../../../_topics/scripting/working-with-files/load"]("C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc["parseError"]["errorCode"] != 0)
{
s = "Reason:\t" + Doc["parseError"]["reason"] + "\n" +
"Line:\t" + aqConvert["VarToStr"](Doc["parseError"]["line"]) + "\n" +
"Pos:\t" + aqConvert["VarToStr"](Doc["parseError"]["linePos"]) + "\n" +
"Source:\t" + Doc["parseError"]["srcText"];
// Post an error to the log and exit
Log["Error"]("Cannot parse the document.", s);
return;
}
// Obtain the node
Node = Doc["documentElement"];
// Process the node
ProcessNode(Node);
}
function ProcessNode(ANode)
{
var FID, Attrs, i, Attr, ChildNodes;
// Create a log folder for each node and activate the folder
FID = Log["CreateFolder"](ANode["nodeName"]);
Log["PushLogFolder"](FID);
// If the node value is not null, output it
if( aqObject["GetVarType"](ANode["nodeValue"]) != 1)
Log["Message"]("Value: " + aqConvert["VarToStr"](ANode["nodeValue"]));
// Process the node's attributes
// Exclude helper nodes from processing
if( ANode["nodeName"]["charAt"](0) != "\#")
{
// Obtain the attribute collection and
// output the attributes to the log
Attrs = ANode["attributes"];
for(i = 0; i < Attrs["length"]; i++)
{
Attr = Attrs["item"](i);
Log.Message("Attr " + Attr["nodeName"] + ": " + Attr["nodeValue"]);
}
}
// Obtain the collection of child nodes
ChildNodes = ANode["childNodes"];
// Processes each node of the collection
for(i = 0; i < ChildNodes["length"]; i++)
ProcessNode(ChildNodes["item"](i));
// Close the log folder
Log["PopLogFolder"]();
}
In this example, the TestXML
procedure creates a new XML DOM Document object via COM and loads data from the Data.xml file. When loading, the XML parser validates the document. The script also checks the result of the validation using the parseError
object. If the file has been loaded successfully, the test obtains the root node and passes it to the ProcessNode
routine for processing.
The ProcessNode
routine posts the node’s name and value to the log (if the node does not contain a value, the value is not posted). Then the routine processes the node's attributes and child nodes.
Example 2: Using XPath Expressions to Parse XML Files
To parse XML files with DOM objects, you can also use XPath expressions. This will allow you to easily get a list of needed nodes without parsing the whole document. The following code shows how you can get a collection of nodes and process subnodes.
JavaScript
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = getActiveXObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = getActiveXObject("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
// Use an XPath expression to obtain a list of "control" nodes
Nodes = Doc.selectNodes("//control");
// Process the node
for(i = 0; i < Nodes.length; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes.item(i);
// Get child nodes
ChildNodes = Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text);
}
}
JScript
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = Sys.OleObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys.OleObject("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
// Use an XPath expression to obtain a list of "control" nodes
Nodes = Doc.selectNodes("//control");
// Process the node
for(i = 0; i < Nodes.length; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes.item(i);
// Get child nodes
ChildNodes = Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text);
}
}
Python
def TestWithXPath():
# Create a COM object
# If you have MSXML 4:
Doc = Sys.OleObject["Msxml2.DOMDocument.4.0"]
# If you have MSXML 6:
Doc = Sys.OleObject["Msxml2.DOMDocument.6.0"]
Doc.async = False
# Load data from a file
# We use the file created earlier
Doc.load("C:\\Data.xml")
# Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode != 0:
s = "Reason:\t" + Doc.parseError.reason + "\n" + "Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" + "Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" + "Source:\t" + Doc.parseError.srcText
# Post an error to the log and exit
Log.Error("Cannot parse the document.", s)
return
# Use an XPath expression to obtain a list of "control" nodes
Nodes = Doc.selectNodes("//control")
# Process the node
for i in range(Nodes.length):
# Get the node from the collection of the found nodes
Node = Nodes.item[i]
# Get child nodes
ChildNodes = Node.childNodes
# Output two child nodes to the log
Log.Message(ChildNodes.item[1].text + ": " + ChildNodes.item[2].text)
VBScript
Sub TestWithXPath
' Create a COM object
' If you have MSXML 4:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.4.0")
' If you have MSXML 6:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.6.0")
Doc.async = False
' Load data from a file
' We use the file created earlier
Call Doc.load("../../../../_topics/scripting/working-with-files/C:\Data.xml")
' Report an error, if, for instance, the markup or file structure is invalid
If Doc.parseError.errorCode <> 0 Then
s = "Reason:" + Chr(9) + Doc.parseError.reason + _
"Line:" + Chr(9) + CStr(Doc.parseError.line) + Chr(13) + Chr(10) + _
"Pos:" + Chr(9) + CStr(Doc.parseError.linePos) + Chr(13) + Chr(10) + _
"Source:" + Chr(9) + Doc.parseError.srcText
' Post an error to the log and exit
Call Log.Error("Cannot parse the document.", s)
Exit Sub
End If
' Use an XPath expression to obtain a list of "control" nodes
Set Nodes = Doc.selectNodes("//control")
' Process the node
For i = 0 to Nodes.length - 1
' Get the node from the collection of the found nodes
Set Node = Nodes.item(i)
' Get child nodes
Set ChildNodes = Node.childNodes
' Output two child nodes to the log
Call Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text)
Next
End Sub
DelphiScript
procedure TestWithXPath;
var
Doc, s, Nodes, ChildNodes, i, Node : OleVariant;
begin
// Create a COM object
// If you have MSXML 4:
Doc := Sys.OleObject('Msxml2.DOMDocument.4.0');
// If you have MSXML 6:
Doc := Sys.OleObject('Msxml2.DOMDocument.6.0');
Doc.async := false;
// Load data from a file
// We use the file created earlier
Doc.load('C:\Data.xml');
// Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode <> 0 then
begin
s := 'Reason:' + #9 + Doc.parseError.reason + #13#10 +
'Line:' + #9 + aqConvert.VarToStr(Doc.parseError.line) + #13#10 +
'Pos:' + #9 + aqConvert.VarToStr(Doc.parseError.linePos) + #13#10 +
'Source:' + #9 + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error('Cannot parse the document.', s);
Exit;
end;
// Use an XPath expression to obtain a list of "control" nodes
Nodes := Doc.selectNodes('//control');
// Process the node
for i := 0 to Nodes.length - 1 do
begin
// Get the node from the collection of the found nodes
Node := Nodes.item(i);
// Get child nodes
ChildNodes := Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ': ' + ChildNodes.item(2).text);
end;
end;
C++Script, C#Script
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.6.0");
Doc["async"] = false;
// Load data from a file
// We use the file created earlier
Doc["../../../../_topics/scripting/working-with-files/load"]("C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc["parseError"]["errorCode"] != 0)
{
s = "Reason:\t" + Doc["parseError"]["reason"] + "\n" +
"Line:\t" + aqConvert["VarToStr"](Doc["parseError"]["line"]) + "\n" +
"Pos:\t" + aqConvert["VarToStr"](Doc["parseError"]["linePos"]) + "\n" +
"Source:\t" + Doc["parseError"]["srcText"];
// Post an error to the log and exit
Log["Error"]("Cannot parse the document.", s);
return;
}
// Use an XPath expression to obtain a list of "control" nodes
Nodes = Doc["selectNodes"]("//control");
// Process the node
for(i = 0; i < Nodes["length"]; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes["item"](i);
// Get child nodes
ChildNodes = Node["childNodes"];
// Output two child nodes to the log
Log["Message"](ChildNodes["item"](1)["text"] + ": " + ChildNodes["item"](2)["text"]);
}
}
The code above is very similar to the previous example. The only difference is that we call the selectNodes
method and pass it an XPath expression. The method returns a collection of the requested objects. Then we parse the collection.
Example 3: Parsing Nodes With Namespaces
The previous examples do not return nodes that have a namespace. The code below shows how to get a node with a namespace and process its child nodes.
JavaScript
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = getActiveXObject("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = getActiveXObject("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
//Define the namespace of the node
Doc.setProperty('SelectionNamespaces', 'xmlns:a="CheckBoxes"');
//Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Nodes = Doc.selectNodes("//a:control");
// Process the node
for(i = 0; i < Nodes.length; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes.item(i);
// Get child nodes
ChildNodes = Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text);
}
}
JScript
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = Sys.Ole.Object("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys.Ole.Object("Msxml2.DOMDocument.6.0");
Doc.async = false;
// Load data from a file
// We use the file created earlier
Doc.load("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc.parseError.errorCode != 0)
{
s = "Reason:\t" + Doc.parseError.reason + "\n" +
"Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" +
"Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" +
"Source:\t" + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error("Cannot parse the document.", s);
return;
}
//Define the namespace of the node
Doc.setProperty('SelectionNamespaces', 'xmlns:a="CheckBoxes"');
//Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Nodes = Doc.selectNodes("//a:control");
// Process the node
for(i = 0; i < Nodes.length; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes.item(i);
// Get child nodes
ChildNodes = Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text);
}
}
Python
def TestWithXPath():
# Create a COM object
# If you have MSXML 4:
Doc = Sys.OleObject["Msxml2.DOMDocument.4.0"]
# If you have MSXML 6:
Doc = Sys.OleObject["Msxml2.DOMDocument.6.0"]
Doc.async = False
# Load data from a file
# We use the file created earlier
Doc.load("C:\\Data.xml")
# Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode != 0:
s = "Reason:\t" + Doc.parseError.reason + "\n" + "Line:\t" + aqConvert.VarToStr(Doc.parseError.line) + "\n" + "Pos:\t" + aqConvert.VarToStr(Doc.parseError.linePos) + "\n" + "Source:\t" + Doc.parseError.srcText
# Post an error to the log and exit
Log.Error("Cannot parse the document.", s)
return
# Define the namespace of the node
Doc.setProperty('SelectionNamespaces', 'xmlns:a="CheckBoxes"')
# Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Nodes = Doc.selectNodes("//a:control")
# Process the node
for i in range(Nodes.length):
# Get the node from the collection of the found nodes
Node = Nodes.item(i)
# Get child nodes
ChildNodes = Node.childNodes
# Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text)
VBScript
Sub TestWithXPath
' Create a COM object
' If you have MSXML 4:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.4.0")
' If you have MSXML 6:
Set Doc = Sys.OleObject("Msxml2.DOMDocument.6.0")
Doc.async = False
' Load data from a file
' We use the file created earlier
Call Doc.load("../../../../_topics/scripting/working-with-files/C:\Data.xml")
' Report an error, if, for instance, the markup or file structure is invalid
If Doc.parseError.errorCode <> 0 Then
s = "Reason:" + Chr(9) + Doc.parseError.reason + _
"Line:" + Chr(9) + CStr(Doc.parseError.line) + Chr(13) + Chr(10) + _
"Pos:" + Chr(9) + CStr(Doc.parseError.linePos) + Chr(13) + Chr(10) + _
"Source:" + Chr(9) + Doc.parseError.srcText
' Post an error to the log and exit
Call Log.Error("Cannot parse the document.", s)
Exit Sub
End If
' Define the namespace of the node
Doc.setProperty "SelectionNamespaces", "xmlns:a='CheckBoxes'"
' Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Set Nodes = Doc.selectNodes("//a:control")
' Process the node
For i = 0 to Nodes.length - 1
' Get the node from the collection of the found nodes
Set Node = Nodes.item(i)
' Get child nodes
Set ChildNodes = Node.childNodes
' Output two child nodes to the log
Call Log.Message(ChildNodes.item(1).text + ": " + ChildNodes.item(2).text)
Next
End Sub
DelphiScript
procedure TestWithXPath;
var
Doc, s, Nodes, ChildNodes, i, Node : OleVariant;
begin
// Create a COM object
// If you have MSXML 4:
Doc := Sys.OleObject('Msxml2.DOMDocument.4.0');
// If you have MSXML 6:
Doc := Sys.OleObject('Msxml2.DOMDocument.6.0');
Doc.async := false;
// Load data from a file
// We use the file created earlier
Doc.load('C:\Data.xml');
// Report an error, if, for instance, the markup or file structure is invalid
if Doc.parseError.errorCode <> 0 then
begin
s := 'Reason:' + #9 + Doc.parseError.reason + #13#10 +
'Line:' + #9 + aqConvert.VarToStr(Doc.parseError.line) + #13#10 +
'Pos:' + #9 + aqConvert.VarToStr(Doc.parseError.linePos) + #13#10 +
'Source:' + #9 + Doc.parseError.srcText;
// Post an error to the log and exit
Log.Error('Cannot parse the document.', s);
Exit;
end;
//Define the namespace of the node
Doc.setProperty('SelectionNamespaces', 'xmlns:a="CheckBoxes"');
// Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Nodes := Doc.selectNodes('//a:control');
// Process the node
for i := 0 to Nodes.length - 1 do
begin
// Get the node from the collection of the found nodes
Node := Nodes.item(i);
// Get child nodes
ChildNodes := Node.childNodes;
// Output two child nodes to the log
Log.Message(ChildNodes.item(1).text + ': ' + ChildNodes.item(2).text);
end;
end;
C++Script, C#Script
function TestWithXPath()
{
var Doc, s, Nodes, ChildNodes, i, Node;
// Create a COM object
// If you have MSXML 4:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.4.0");
// If you have MSXML 6:
Doc = Sys["OleObject"]("Msxml2.DOMDocument.6.0");
Doc["async"] = false;
// Load data from a file
// We use the file created earlier
Doc["../../../../_topics/scripting/working-with-files/load"]("C:\\Data.xml");
// Report an error, if, for instance, the markup or file structure is invalid
if(Doc["parseError"]["errorCode"] != 0)
{
s = "Reason:\t" + Doc["parseError"]["reason"] + "\n" +
"Line:\t" + aqConvert["VarToStr"](Doc["parseError"]["line"]) + "\n" +
"Pos:\t" + aqConvert["VarToStr"](Doc["parseError"]["linePos"]) + "\n" +
"Source:\t" + Doc["parseError"]["srcText"];
// Post an error to the log and exit
Log["Error"]("Cannot parse the document.", s);
return;
}
//Define the namespace of the node
Doc.setProperty('SelectionNamespaces', 'xmlns:a="CheckBoxes"');
// Use an XPath expression to obtain a list of "control" nodes with the "Checkboxes" namespace
Nodes = Doc["selectNodes"]("//a:control");
// Process the node
for(i = 0; i < Nodes["length"]; i++)
{
// Get the node from the collection of the found nodes
Node = Nodes["item"](i);
// Get child nodes
ChildNodes = Node["childNodes"];
// Output two child nodes to the log
Log["Message"](ChildNodes["item"](1)["text"] + ": " + ChildNodes["item"](2)["text"]);
}
}
The code above is very similar to the previous examples. In this example, we define the SelectionNamespaces
property in the setProperty
expression and pass it an XPath expression to process only the node with the specified namespace. Namespaces are case-sensitive.
Using the Storages Object
The code below demonstrates how to use the Storage
object’s methods to store values in an XML file and read data from that file:
JavaScript, JScript
function StoragesSaveXML()
{
var FileSection, Section;
// Create an empty section
FileSection = Storages.XML("");
// Create a subsection and add options to it
Section = FileSection.GetSubSection("Section1");
Section.SetOption("Option1", 1); // Add an integer option
Section.SetOption("Option2", aqDateTime.Now()); // Add Date/Time option
Section.SetOption("Option3", "String1"); // Add string option
// Another section and more options
Section = FileSection.GetSubSection("Section2");
Section.SetOption("Option1", 2);
Section.SetOption("Option2", aqDateTime.Now());
Section.SetOption("Option3", "String2");
// One more section and more options
Section = FileSection.GetSubSection("Section3");
Section.SetOption("Option1", 3);
Section.SetOption("Option2", aqDateTime.Now());
Section.SetOption("Option3", "String3");
// Save data to an XML file
FileSection.SaveAs("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
}
function StoragesLoadXML()
{
var FileSection, Section, i, FID, Option1, Option2, Option3;
// Load data from the XML file created by the previous StoragesSaveXML routine
FileSection = Storages.XML("../../../../_topics/scripting/working-with-files/C:\\Data.xml");
// Iterate through the sections and process values
for(i = 0; i < FileSection.SectionCount; i++)
{
// Get a section
Section = FileSection.GetSubSectionByIndex(i);
// Create a folder ...
FID = Log.CreateFolder(FileSection.GetSectionName(i));
Log.PushLogFolder(FID);
// ... and output data to the log
Option1 = Section.GetOption("Option1", 0);
Log.Message("Option1: " + aqConvert.VarToStr(Option1));
Option2 = Section.GetOption("Option2", 0);
Log.Message("Option2: " + aqConvert.VarToStr(Option2));
Option3 = Section.GetOption("Option3", 0);
Log.Message("Option3: " + aqConvert.VarToStr(Option3));
// Close the folder
Log.PopLogFolder();
}
}
Python
def StoragesSaveXML():
# Create an empty section
FileSection = Storages.XML("")
# Create a subsection and add options to it
Section = FileSection.GetSubSection("Section1")
Section.SetOption("Option1", 1) # Add an integer option
Section.SetOption("Option2", aqDateTime.Now()) # Add Date/Time option
Section.SetOption("Option3", "String1") # Add string option
# Another section and more options
Section = FileSection.GetSubSection("Section2")
Section.SetOption("Option1", 2)
Section.SetOption("Option2", aqDateTime.Now())
Section.SetOption("Option3", "String2")
# One more section and more options
Section = FileSection.GetSubSection("Section3")
Section.SetOption("Option1", 3)
Section.SetOption("Option2", aqDateTime.Now())
Section.SetOption("Option3", "String3")
# Save data to an XML file
FileSection.SaveAs("C:\\Data.xml")
def StoragesLoadXML():
# Load data from the XML file created by the previous StoragesSaveXML routine
FileSection = Storages.XML("C:\\Data.xml")
# Iterate through the sections and process values
for i in range(FileSection.SectionCount) :
# Get a section
Section = FileSection.GetSubSectionByIndex(i)
# Create a folder ...
FID = Log.CreateFolder(FileSection.GetSectionName(i))
Log.PushLogFolder(FID)
# ... and output data to the log
Option1 = Section.GetOption("Option1", 0)
Log.Message("Option1: " + aqConvert.VarToStr(Option1))
Option2 = Section.GetOption("Option2", 0)
Log.Message("Option2: " + aqConvert.VarToStr(Option2))
Option3 = Section.GetOption("Option3", 0)
Log.Message("Option3: " + aqConvert.VarToStr(Option3))
# Close the folder
Log.PopLogFolder()
VBScript
Sub StoragesSaveXML
' Create an empty section
Set FileSection = Storages.XML("")
' Create a subsection and add options to it
Set Section = FileSection.GetSubSection("Section1")
Section.SetOption "Option1", 1 ' Add an integer option
Section.SetOption "Option2", aqDateTime.Now() ' Add Date/Time option
Section.SetOption "Option3", "String1" ' Add string option
' Another section and more options
Set Section = FileSection.GetSubSection("Section2")
Section.SetOption "Option1", 2
Section.SetOption "Option2", aqDateTime.Now()
Section.SetOption "Option3", "String2"
' One more section and more options
Set Section = FileSection.GetSubSection("Section3")
Section.SetOption "Option1", 3
Section.SetOption "Option2", aqDateTime.Now()
Section.SetOption "Option3", "String3"
' Save data to an XML file
FileSection.SaveAs("../../../../_topics/scripting/working-with-files/C:\Data.xml")
End Sub
Sub StoragesLoadXML
' Load data from the XML file created by the previous StoragesSaveXML routine
Set FileSection = Storages.XML("../../../../_topics/scripting/working-with-files/C:\Data.xml")
' Iterate through the sections and process values
For i = 0 to FileSection.SectionCount - 1
' Get a section
Set Section = FileSection.GetSubSectionByIndex(i)
' Create a folder ...
FID = Log.CreateFolder(FileSection.GetSectionName(i))
Log.PushLogFolder FID
' ... and output data to the log
Option1 = Section.GetOption("Option1", 0)
Call Log.Message("Option1: " + aqConvert.VarToStr(Option1))
Option2 = Section.GetOption("Option2", 0)
Call Log.Message("Option2: " + aqConvert.VarToStr(Option2))
Option3 = Section.GetOption("Option3", 0)
Call Log.Message("Option3: " + aqConvert.VarToStr(Option3))
' Close the folder
Log.PopLogFolder
Next
End Sub
DelphiScript
procedure StoragesSaveXML();
var
FileSection, Section : OleVariant;
begin
// Create an empty section
FileSection := Storages.XML('');
// Create a subsection and add options to it
Section := FileSection.GetSubSection('Section1');
Section.SetOption('Option1', 1); // Add an integer option
Section.SetOption('Option2', aqDateTime.Now()); // Add Date/Time option
Section.SetOption('Option3', 'String1'); // Add string option
// Another section and more options
Section := FileSection.GetSubSection('Section2');
Section.SetOption('Option1', 2);
Section.SetOption('Option2', aqDateTime.Now());
Section.SetOption('Option3', 'String2');
// One more section and more options
Section := FileSection.GetSubSection('Section3');
Section.SetOption('Option1', 3);
Section.SetOption('Option2', aqDateTime.Now());
Section.SetOption('Option3', 'String3');
// Save data to an XML file
FileSection.SaveAs('C:\Data.xml');
end;
procedure StoragesLoadXML();
var
FileSection, Section, i, FID, Option1, Option2, Option3 : OleVariant;
begin
// Load data from the XML file created by the previous StoragesSaveXML routine
FileSection := Storages.XML('C:\Data.xml');
// Iterate through the sections and process values
for i := 0 to FileSection.SectionCount - 1 do
begin
// Get a section
Section := FileSection.GetSubSectionByIndex(i);
// Create a folder ...
FID := Log.CreateFolder(FileSection.GetSectionName(i));
Log.PushLogFolder(FID);
// ... and output data to the log
Option1 := Section.GetOption('Option1', 0);
Log.Message('Option1: ' + aqConvert.VarToStr(Option1));
Option2 := Section.GetOption('Option2', 0);
Log.Message('Option2: ' + aqConvert.VarToStr(Option2));
Option3 := Section.GetOption('Option3', 0);
Log.Message('Option3: ' + aqConvert.VarToStr(Option3));
// Close the folder
Log.PopLogFolder();
end;
end;
C++Script, C#Script
function StoragesSaveXML()
{
var FileSection, Section;
// Create an empty section
FileSection = Storages["XML"]("");
// Create a subsection and add options to it
Section = FileSection["GetSubSection"]("Section1");
Section["SetOption"]("Option1", 1); // Add an integer option
Section["SetOption"]("Option2", aqDateTime["Now"]()); // Add Date/Time option
Section["SetOption"]("Option3", "String1"); // Add string option
// Another section and more options
Section = FileSection["GetSubSection"]("Section2");
Section["SetOption"]("Option1", 2);
Section["SetOption"]("Option2", aqDateTime["Now"]());
Section["SetOption"]("Option3", "String2");
// One more section and more options
Section = FileSection["GetSubSection"]("Section3");
Section["SetOption"]("Option1", 3);
Section["SetOption"]("Option2", aqDateTime["Now"]());
Section["SetOption"]("Option3", "String3");
// Save data to an XML file
FileSection["../../../../_topics/scripting/working-with-files/SaveAs"]("C:\\Data.xml");
}
function StoragesLoadXML()
{
var FileSection, Section, i, FID, Option1, Option2, Option3;
// Load data from the XML file created by the previous StoragesSaveXML routine
FileSection = Storages["../../../../_topics/scripting/working-with-files/XML"]("C:\\Data.xml");
// Iterate through the sections and process values
for(i = 0; i < FileSection["SectionCount"]; i++)
{
// Get a section
Section = FileSection["GetSubSectionByIndex"](i);
// Create a folder ...
FID = Log["CreateFolder"](FileSection["GetSectionName"](i));
Log["PushLogFolder"](FID);
// ... and output data to the log
Option1 = Section["GetOption"]("Option1", 0);
Log["Message"]("Option1: " + aqConvert["VarToStr"](Option1));
Option2 = Section["GetOption"]("Option2", 0);
Log["Message"]("Option2: " + aqConvert["VarToStr"](Option2));
Option3 = Section["GetOption"]("Option3", 0);
Log["Message"]("Option3: " + aqConvert["VarToStr"](Option3));
// Close the folder
Log["PopLogFolder"]();
}
}
The code above defines sections and options.
Note: | If the format of the XML file you try to open with the Storage.XML method differs from the format supported by the Storage object’s methods, an error will occur. |
See Also
Script Tests
Storages Object
Working With Files From Scripts
About File Checkpoints