JBoss Community Archive (Read Only)

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

ModeShape 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 ModeShape accepts full-text search language expressions, including wildcard support.

As an aside, ModeShape 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.

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. ModeShape follows this requirement, and does not specifying residual properties. However, ModeShape does allow multi-valued properties to be specified as result columns. And as per the specification, ModeShape always returns the "jcr:path" and "jcr:score" pseudo-columns.

ModeShape 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

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

ModeShape does support using the element test to test against primary or mixin type. ModeShape 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 ModeShape is far more capable of joining multiple sets of nodes with different type, property and path constraints.

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.

ModeShape 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 nodeSet1
ON ISCHILDNODE(nodeSet1,[my:type])
JOIN [nt:base] as nodeSet2
ON 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 nodeSet1
ON ISCHILDNODE(nodeSet1,[my:type])
JOIN [nt:base] as nodeSet2
ON ISCHILDNODE(nodeSet2,nodeSet1)
WHERE nodeSet2.id IS NOT NULLL

//element(*,my:type)[.//@id]

SELECT * FROM [my:type]
JOIN [nt:base] as nodeSet1
ON 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.

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.

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

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.

ModeShape 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.title
FROM [nt:base] AS nodeSet1
ORDER BY nodeSet1.title

//element(,) order by jcr:score()

SELECT *
FROM [nt:base] AS nodeSet1
ORDER BY SCORE(nodeSet1)

//element(*,my:type) order by jcr:score(my:type)

SELECT *
FROM [my:type] AS nodeSet1
ORDER BY SCORE(nodeSet1)

//element(,) order by @jcr:path

SELECT jcr:path
FROM [nt:base] AS nodeSet1
ORDER BY PATH(nodeSet1)

//element(,) order by @title, @jcr:score

SELECT nodeSet1.title
FROM [nt:base] AS nodeSet1
ORDER BY nodeSet1.title,
SCORE(nodeSet1)

Specifying result ordering

Note that the JCR-SQL2 language supported by ModeShape 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.

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.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 12:06:55 UTC, last content change 2012-11-16 13:04:54 UTC.