Section - 5 : Using XPath


XML path locator (XPath) complies with the standard syntax specifications (W3C standards) found in the XML Path Language, but differs in some regards because it was developed to support the Rules Processor in Documaker Server. Because this version of XPath has some limitations, you should check the syntax using the XPATHW32 utility.

XPath Syntax

Here are examples of the valid axes, function calls, signs, and operators to help you understand and use the XPath syntax.

Axes

You have these axes:

Name Used to locate the
ancestor Ancestors of the current context node
ancestor-or-self Ancestors of the current context node and itself
parent Parents of the current context node
descendant Descendants of the current context node
descendant-or-self Descendants of the current context node and itself
attribute Attributes of the current context node
child Children of the current context node
following-sibling Following siblings of the current context node
following Context nodes that follow the current node
preceding-sibling Preceding siblings of the current context node
preceding Context nodes that precede the current node
self Self context node

When used, an axis is always followed by a context node name separated by two colons (::). For example, the syntax descendant::para locates all para descendants of the current context node.

Symbols

You can use these calculation operators:

=    !   =    <    >    +    -

Where !=, <, >, + can be used as calculation operators in function position(), such as, [position()=2], [position()!=2], [3+i], [position()<5], and so on. The equals sign (=) is also used for evaluations such as @Name=’Auto’.

You can use these symbols in a valid XPath:

/    //    *    ::    [    ]    @

Where the pair of brackets ( [ ] ) enclose a condition for evaluation, the at symbol (@) is an abbreviation of the attribute, the asterisk (*) is used for a wild card search, and others are used in a valid XPath, as shown below.

Functions

You can use these functions:

Function Returns
concat(string, string, string… The concatenation of the strings
last() The last element in the selection
name() The name of the selected elements
node() The node names
position() The position of selected elements
text() The text of selected elements
string(object) The string from the context node
xml() The output buffer containing all descendents of the specified element

Expressions

You can use abbreviated syntax with XPath. Here are the valid expressions:

Abbreviated syntax Full syntax
* child::*
para child::para
chapter/para child::chapter/child::para
para[1] child::para[position()=1]
/chapter/para[last()] /child::chapter/child::para[position()=last()]
text() child::text()
node() child::node()
para[@type] child::para[attribute::type]
para[@type="warning"] child::para[attribute::type="warning"]
para[@type="warning"][2+i] child::para[attribute::type="warning"][position()#2+i]
chapter[title] child::chapter[child::title]
chapter[title=’Introduction’] child::chapter[child::title="Introduction"]
doc//para child::doc/descendant-or-self::node()/child::para
@* attribute::*
@type attribute::type
[@name=’warning’] [attribute::name=’warning’]
//para /descendant-or-self::node()/child::para
  self::node()
.//para self::node/descendant-or-self::node()/child::para
.. parent::node()
../chapter parent::node()/child::chapter
../@type parent::node()/attribute::type

Using the XPath Testing Utility

Here is the syntax of the XPATHW32 testing utility:

xpathw32 /f= xml file /e=starting node /x= search path

The /e parameter specifies the node where the search of the XPath starts. You can omit this parameter if you want the search to start from the beginning. A pair of double quotes is required to enclose the search mask. Here is an example:

xpathw32 /f=“d:\test\test.xml” /x=“Forms/Form/Car[@Name=’Car1’]/text()”

This example searches the node Car with the attribute Name=“Car1”. It then retrieves its text and returns a text string similar to this one:

Text string = Car 1 is Toyota

These examples illustrate some search paths most frequently used in Documaker RP applications. Run the testing tool yourself for the answer.

Example 1:

These examples search for a list of nodes with or without conditions. Keep in mind a condition is always placed within brackets, as shown here: [condition].

This Returns
Forms/Form/Car A list of the Car nodes
Forms/Form/Car[@*][position()<3] The first two nodes in the Car node list
Forms/Form/Car[@Name][position()>1] A list of the Car nodes above the first element
Forms/Form/Car[text()][position()!=2] A list of the Car nodes, excluding the second one
Forms/Form/Car[Model] A list of Car nodes that have a child named Model
Forms/Form/Car/node() A list of children nodes under the Car nodes
Forms/Form/Car/Coverage[1] A list of first child Coverage under the Car nodes
Forms/Form/Car[@Name=’Car1’]/Coverage A list of nodes Coverage under Car1

Example 2:

These examples search for the path for a single element:

This Produces
Forms/Form/Car[@*][1] The first node of the Car list with any attributes
Forms/Form/Car[@Name][last()] The last node of the Car list with the attribute Name
Forms/Form/Car[@Name=’Car1’] The Car node with attribute name Car1
Forms/Form/Car[Model=’Toyota’] The Car node with a child Model that has a text string of Toyota.
Forms/Form/Car[Model=’Nissan’]/Coverage[3] The third child node of Coverage under the parent node Car that has a child named Model with a text string of Nissan

Example 3:

These examples search for a list of attributes:

This Produces
Forms/Form/Car[Model=’Nissan’]/@* A list of attributes of the Car node that have a Child node named Model with a value of Nissan
Forms/Form/Car/@Name A list of the attribute Name that has a parent node of Car

Example 4:

These examples search for a single attribute:

This Produces
Forms/Form/Car[Model=’Honda’]/@*[1] The first attribute of the Car node that has a child named Model with a value of Honda
Forms/Form/Car [Model=’Honda’]/@Name The attribute Name of the Car node that has a child named Model with a value of Honda
Forms/Form/Car[1]/@Name The attribute Name of first Car node

Example 5:

These examples search for a list of text strings:

This Produces
Forms/Form/Car/text() A list of text strings of Car nodes
Forms/Form/Car[Model]/text() A list of text strings of Car nodes which have children named Model

Example 6:

These examples search for a single text string:

This Produces
Forms/Form/Car[Model=’Toyota’]/text() The text string of the Car node which has a child name Model with a value of Toyota
Forms/Form/Car[Model='Honda']/parent::*/text() The text string of the node Form which has a child named Car that, in turn, has a child named Model with a value of Honda

Note: There are three types of returned lists: elements, attributes, and text. When a list includes only one element, the structure returns a single element instead of a list.

Example 7:

These examples search for the name of elements:

This Produces
//*[name()=’Car’] “Car” nodes
Forms/Form/*[name()=’Car’][2]/text() A text string of second “Car” nodes

Example 8:

These examples concatenate text strings:

This Produces
concat('Car1', 'and', 'Car2')" A string “Car1 and Car2”
concat(//Car[@Name='Car1'], 'and',//Car[@Name='Car3'], 'are imported cars.')) A string “Toyata and Nissan are imported cars.”

Example 9:

These examples search for strings:

This Produces
string(‘ 12345’) The string “ 12345”
string(//Car[2]/*[1]) The string of the first child of the second Car node

Example 10:

This examples returns a buffer that contains all descendants of the specified element:

This Produces
xpathw32 /f=cars.xml /x="//Car[2]/xml() <Car Name=" Car2">Car 2 is Honda
<Model>Honda</Model>
<Coverage>Cover 4</Coverage>
<Coverage>Cover 5</Coverage>
<Coverage>Cover 6</Coverage>
</Car>

Note that the XPath must point to a single element, such as Car[2] in the example.

Example XML File

Here is an example XML file (TEST.XML):

<?xml version="1.0" encoding="UTF-8"?>

<!--Sample XML file generated by XML Spy v4.2 U (http://www.xmlspy.com)-->

<Forms>

<Form>

<Car Name="Car1">Car 1 is Toyota

<Model>Toyota</Model>

<Coverage>Cover 1</Coverage>

<Coverage>Cover 2</Coverage>

<Coverage>Cover 3</Coverage>

</Car>

<Car Name="Car2">Car 2 is Honda

<Model>Honda</Model>

<Coverage>Cover 4</Coverage>

<Coverage>Cover 5</Coverage>

<Coverage>Cover 6</Coverage>

</Car>

<Car Name="Car3">Car 3 is Nissan

<Model>Nissan</Model>

<Coverage>Cover 7</Coverage>

<Coverage>Cover 8</Coverage>

<Coverage>Cover 9</Coverage>

</Car>

</Form>

</Forms>