Red Hat Training

A Red Hat training course is available for Red Hat JBoss Data Virtualization

7.3. XPath

The JCR 1.0 specification uses the XPath query language because node structures in JCR are very analogous to the structure of an XML document. Thus, XPath provides a useful language for selecting and searching workspace content. And since JCR 1.0 defines a mapping between XML and a workspace view called the "document view", adapting XPath to workspace content is quite natural.
A JCR XPath query specifies the subset of nodes in a workspace that satisfy the constraints defined in the query. Constraints can limit the nodes in the results to be those nodes with a specific (primary or mixin) node type, with properties having particular values, or to be within a specific subtree of the workspace. The query also defines how the nodes are to be returned in the result sets using column specifiers and ordering specifiers.

7.3.1. Extensions to XPath

The hierarchical database offers a bit more functionality in the jcr:contains(...) clauses than required by the specification. In particular, the second parameter specifies the search expression, and for these full-text search language expressions are accepted, including wildcard support.

Important

As an aside, the hierarchical database actually implements XPath queries by transforming them into the equivalent JCR-SQL2 representation. And the JCR-SQL2 language, although often more verbose, is much more capable of representing complex queries with multiple combinations of type, property, and path constraints.

7.3.2. Column Specifiers

JCR 1.0 specifies that support is required only for returning column values based upon single-valued, non-residual properties that are declared on or inherited by the node types specified in the type constraint. The hierarchical database follows this requirement, and does not specifying residual properties. However, the hierarchical database does allow multi-valued properties to be specified as result columns. And as per the specification, the hierarchical database always returns the jcr:path and jcr:score pseudo-columns.
The hierarchical database uses the last location step with an attribute axis to specify the properties that are to be returned as result columns. Multiple properties are specified with a union. For example, the following table shows several XPath queries and how they map to JCR-SQL2 queries.
XPath
JCR-SQL2
//*
SELECT * FROM [nt:base]
//element(*,my:type)
SELECT * FROM [my:type]
//element(*,my:type)/@my:title
SELECT [my:title] FROM [my:type]
//element(*,my:type)/(@my:title | @my:text)
SELECT [my:title], [my:text] FROM [my:type]
//element(*,my:type)/(@my:title union @my:text)
SELECT [my:title], [my:text] FROM [my:type]
Specifying result set columns

7.3.3. Type Constraints

JCR 1.0 specifies that support is required only for specifying constraints of one primary type, and it is optional to support specifying constraints on one (or more) mixin types. The specification also defines that the XPath element test be used to test against node types, and that it is optional to support element tests on location steps other than the last one. Type constraints are inherently inheritance-sensitive, in that a constraint against a particular node type 'X' will be satisfied by nodes explicitly declared to be of type 'X' or of subtypes of 'X'.
The hierarchical database does support using the element test to test against primary or mixin type. The hierarchical database also only supports using an element test on the last location step. For example, the following table shows several XPath queries and how they map to JCR-SQL2 queries.
XPath
JCR-SQL2
//*
SELECT * FROM [nt:base]
//element(*,my:type)
SELECT * FROM [my:type]
/jcr:root/nodes/element(*,my:type)
SELECT * FROM [my:type]WHERE PATH([my:type])> LIKE '/nodes/%' {{AND DEPTH([my:type]) = CAST(2 AS LONG) }}
/jcr:root/nodes//element(*,my:type)
SELECT * FROM [my:type]WHERE PATH([my:type]) LIKE '/nodes/%'
/jcr:root/nodes//element(ex:nodeName,my:type)
SELECT * FROM [my:type]WHERE PATH([my:type]) LIKE '/nodes/%'AND NAME([my:type]) = 'ex:nodeName'
Specifying type constraints
Note that the JCR-SQL2 language supported by the hierarchical database is far more capable of joining multiple sets of nodes with different type, property and path constraints.

7.3.4. Property Constraints

JCR 1.0 specifies that attribute tests on the last location step is required, but that predicate tests on any other location steps are optional.
The hierarchical database does support using attribute tests on the last location step to specify property constraints, as well as supporting axis and filter predicates on other location steps. For example, the following table shows several XPath queries and how they map to JCR-SQL2 queries.
XPath
JCR-SQL2
//*[]
SELECT * FROM [nt:base]WHERE [nt:base].prop1 IS NOT NULL
//element(*,my:type)[@prop1]
SELECT * FROM [my:type]WHERE [my:type].prop1 IS NOT NULL
//element(*,my:type)[@prop1=xs:boolean('true')]
SELECT * FROM [my:type]WHERE [my:type].prop1 = CAST('true' AS BOOLEAN)
//element(*,my:type)[@id<1 and @name='john']
SELECT * FROM [my:type]WHERE id < 1 AND name = 'john'
//element(*,my:type)[a/b/@id]
SELECT * FROM [my:type]JOIN [nt:base] as nodeSet1ON ISCHILDNODE(nodeSet1,[my:type])JOIN [nt:base] as nodeSet2ON ISCHILDNODE(nodeSet2,nodeSet1)WHERE (NAME(nodeSet1) = 'a' {{AND NAME(nodeSet2) = 'b') }} AND nodeSet2.id IS NOT NULL]
//element(,my:type)[./ { }{}/*/@id]
SELECT * FROM [my:type]JOIN [nt:base] as nodeSet1ON ISCHILDNODE(nodeSet1,[my:type])JOIN [nt:base] as nodeSet2ON ISCHILDNODE(nodeSet2,nodeSet1)WHERE nodeSet2.id IS NOT NULLL
//element(*,my:type)[.//@id]
SELECT * FROM [my:type]JOIN [nt:base] as nodeSet1ON ISDESCENDANTNODE(nodeSet1,[my:type])WHERE nodeSet2.id IS NOT NULLL
Specifying property constraints
Section 6.6.3.3 of the JCR 1.0 specification contains an in-depth description of property value constraints using various comparison operators.

7.3.5. Path Constraints

JCR 1.0 specifies that exact, child node, and descendants-or-self path constraints be supported on the location steps in an XPath query.
The hierarchical database does support the four kinds of path constraints. For example, the following table shows several XPath queries and how they map to JCR-SQL2 queries.
XPath
JCR-SQL2
/jcr:root/a[1]/b[2]
SELECT * FROM [nt:base]WHERE PATH([nt:base]) = '/a[1]/b[2]'
/jcr:root/a/b[*]
SELECT * FROM [nt:base]WHERE PATH([nt:base]) = '/a[%]/b[%]'
/jcr:root/a[1]/b[*]
SELECT * FROM [nt:base]WHERE PATH([nt:base]) = '/a[%]/b[%]'
/jcr:root/a[2]/b
SELECT * FROM [nt:base]WHERE PATH([nt:base]) = '/a[2]/b[%]'
/jcr:root/a/b[2]//c[4]
SELECT * FROM [my:type]WHERE PATH([nt:base]) = '/a[%]/b[2]/c[4]'OR PATH(nodeSet1) LIKE '/a[%]/b[\2]/%/c[\4]'
/jcr:root/a/b//c//d
SELECT * FROM [my:type]WHERE PATH([nt:base]) = '/a[%]/b[%]/c[%]/d[%]'OR PATH([nt:base]) LIKE '/a[%]/b[%]/%/c[%]/d[%]'OR PATH([nt:base]) LIKE '/a[%]/b[%]/c[%]/%/d[%]'OR PATH([nt:base]) LIKE '/a[%]/b[%]/%/c[%]/%/d[%]'
//element(*,my:type)[@id<1 and @name='john']
SELECT * FROM [my:type]WHERE id < 1 AND name = 'john'
/jcr:root/a/b//element(*,my:type)
SELECT * FROM [my:type]WHERE PATH([my:type]) = '/a[%]/b[%]/%'
Specifying path constraints
Note that the JCR-SQL2 language supported by the hierarchical database is capable of representing a wider combination of path constraints, although the XPath expressions are easier to understand and significantly shorter.
Also, path constraints in XPath do not need to specify wildcards for the same-name-sibling (SNS) indexes, as XPath should naturally find all nodes regardless of the SNS index, unless the SNS index is explicitly specified. In other words, any path segment that does not have an explicit SNS index (or an SNS index of '[%]' or '[ ]') will match _all SNS index values. However, any segments in the path expression that have an explicit numeric SNS index will require an exact match. Thus this path constraint:
/a/b/c\[2]/d\[%]/\%/e\[_]
will effectively be converted into
/a[%]/b[%]/c\[2]/d\[%]/\%/e\[_]
This behavior is very different than how JCR-SQL and JCR-SQL2 path constraints are handled, since these languages interpret a lack of a SNS index as equating to '[1]'. To achieve the XPath-like matching, a query written in JCR-SQL or JCR-SQL2 would need to explicitly include '[%]' in each path segment where an SNS index literal is not already specified.

7.3.6. Ordering Specifiers

JCR 1.0 extends the XPath grammar to add support for ordering the results according to the natural ordering of the values of one or more properties on the nodes.
The hierarchical database does support zero or more ordering specifiers, including whether each specifier is ascending or descending. If no ordering specifiers are defined, the ordering of the results is not predefined and may vary (though ordering by score may be used by default). For example, the following table shows several XPath queries and how they map to JCR-SQL2 queries.
XPath
JCR-SQL2
//element(,) order by @title
SELECT nodeSet1.titleFROM [nt:base] AS nodeSet1ORDER BY nodeSet1.title
//element(,) order by jcr:score()
SELECT *FROM [nt:base] AS nodeSet1ORDER BY SCORE(nodeSet1)
//element(*,my:type) order by jcr:score(my:type)
SELECT *FROM [my:type] AS nodeSet1ORDER BY SCORE(nodeSet1)
//element(,) order by @jcr:path
SELECT jcr:pathFROM [nt:base] AS nodeSet1ORDER BY PATH(nodeSet1)
//element(,) order by @title, @jcr:score
SELECT nodeSet1.titleFROM [nt:base] AS nodeSet1ORDER BY nodeSet1.title,SCORE(nodeSet1)
Specifying result ordering
Note that the JCR-SQL2 language supported by the hierarchical database has a far richer ORDER BY clause, allowing the use of any kind of dynamic operand, including ordering upon arithmetic operations of multiple dynamic operands.

7.3.7. Miscellaneous

JCR 1.0 defines a number of other optional and required features, and these are summarized in this section.
  • Only abbreviated XPath syntax is supported.
  • Only the child axis (the default axis, represented by '/' in abbreviated syntax), descendant-or-self axis (represented by '//' in abbreviated syntax), self axis (represented by '.' in abbreviated syntax), and attribute axis (represent by '@' in abbreviated syntax) are supported.
  • The text() node test is not supported.
  • The element() node test is supported.
  • The jcr:like() function is supported.
  • The jcr:contains() function is supported.
  • The jcr:score() function is supported.
  • The jcr:deref() function is not supported.