29.6. Expressions
Result type
By default, an XPath expression returns a list of one or more XML nodes, of
org.w3c.dom.NodeList
type. You can use the type converter mechanism to convert the result to a different type, however. In the Java DSL, you can specify the result type in the second argument of the xpath()
command. For example, to return the result of an XPath expression as a String
:
xpath("/person/name/text()", String.class)
In the XML DSL, you can specify the result type in the
resultType
attribute, as follows:
<xpath resultType="java.lang.String">/person/name/text()</xpath>
Patterns in location paths
You can use the following patterns in XPath location paths:
/people/person
- The basic location path specifies the nested location of a particular element. That is, the preceding location path would match the person element in the following XML fragment:
<people> <person>...</person> </people>
Note that this basic pattern can match multiple nodes—for example, if there is more than oneperson
element inside thepeople
element. /name/text()
- If you just want to access the text inside by the element, append
/text()
to the location path, otherwise the node includes the element's start and end tags (and these tags would be included when you convert the node to a string). /person/telephone/@isDayTime
- To select the value of an attribute, AttributeName, use the syntax
@AttributeName
. For example, the preceding location path returnstrue
when applied to the following XML fragment:<person> <telephone isDayTime="true">1234567890</telephone> </person>
*
- A wildcard that matches all elements in the specified scope. For example,
/people/person/*
matches all the child elements ofperson
. @*
- A wildcard that matches all attributes of the matched elements. For example,
/person/name/@*
matches all attributes of every matchedname
element. //
- Match the location path at every nesting level. For example, the
//name
pattern matches everyname
element highlighted in the following XML fragment:<invoice> <person> <name .../> </person> </invoice> <person> <name .../> </person> <name .../>
..
- Selects the parent of the current context node. Not normally useful in the Apache Camel XPath language, because the current context node is the document root, which has no parent.
node()
- Match any kind of node.
text()
- Match a text node.
comment()
- Match a comment node.
processing-instruction()
- Match a processing-instruction node.
Predicate filters
You can filter the set of nodes matching a location path by appending a predicate in square brackets,
[Predicate]
. For example, you can select the Nth node from the list of matches by appending [N]
to a location path. The following expression selects the first matching person
element:
/people/person[1]
The following expression selects the second-last
person
element:
/people/person[last()-1]
You can test the value of attributes in order to select elements with particular attribute values. The following expression selects the
name
elements, whose surname
attribute is either Strachan or Davies:
/person/name[@surname="Strachan" or @surname="Davies"]
You can combine predicate expressions using any of the conjunctions
and
, or
, not()
, and you can compare expressions using the comparators, =
, !=
, >
, >=
, <
, <=
(in practice, the less-than symbol must be replaced by the <
entity). You can also use XPath functions in the predicate filter.
Axes
When you consider the structure of an XML document, the root element contains a sequence of children, and some of those child elements contain further children, and so on. Looked at in this way, where nested elements are linked together by the child-of relationship, the whole XML document has the structure of a tree. Now, if you choose a particular node in this element tree (call it the context node), you might want to refer to different parts of the tree relative to the chosen node. For example, you might want to refer to the children of the context node, to the parent of the context node, or to all of the nodes that share the same parent as the context node (sibling nodes).
An XPath axis is used to specify the scope of a node match, restricting the search to a particular part of the node tree, relative to the current context node. The axis is attached as a prefix to the node name that you want to match, using the syntax,
AxisType::MatchingNode
. For example, you can use the child::
axis to search the children of the current context node, as follows:
/invoice/items/child::item
The context node of
child::item
is the items
element that is selected by the path, /invoice/items
. The child::
axis restricts the search to the children of the context node, items
, so that child::item
matches the children of items
that are named item
. As a matter of fact, the child::
axis is the default axis, so the preceding example can be written equivalently as:
/invoice/items/item
But there several other axes (13 in all), some of which you have already seen in abbreviated form:
@
is an abbreviation of attribute::
, and //
is an abbreviation of descendant-or-self::
. The full list of axes is as follows (for details consult the reference below):
ancestor
ancestor-or-self
attribute
child
descendant
descendant-or-self
following
following-sibling
namespace
parent
preceding
preceding-sibling
self
Functions
XPath provides a small set of standard functions, which can be useful when evaluating predicates. For example, to select the last matching node from a node set, you can use the last() function, which returns the index of the last node in a node set, as follows:
/people/person[last()]
Where the preceding example selects the last
person
element in a sequence (in document order).
For full details of all the functions that XPath provides, consult the reference below.
Reference
For full details of the XPath grammar, see the XML Path Language, Version 1.0 specification.