depage-xmldb understands a small dialect of XPath. Most queries are translated into SQL and answered by the database directly. Queries that the SQL translation cannot express are evaluated with the DOM XPath engine of PHP instead.
The dialect is implemented by XpathParser and XpathElement, the queries are answered by XmlDb::getNodeIdsByXpath() and Document::getNodeIdsByXpath().
A path is a list of steps, separated by /:
| Part | Meaning |
|---|---|
| / | the path starts at the root node of the document |
| // | the descendant axis: all nodes below the current one |
| ns:name | a node with the given namespace prefix and name |
| name | a node without a namespace |
| * | any name |
| *:name | any namespace, the given name (XPath 2.0 syntax) |
| pg:* | the given namespace, any name |
| *g:f* | wildcards in the namespace and in the name |
| [...] | a predicate, see below |
A namespace prefix is matched literally, it is not resolved to its URI before the query is executed.
Matches all nodes that have the attribute, no matter which value it has.
The value may be written in single or in double quotes. Only the = operator is evaluated by the database, all other operators need the DOM XPath fallback.
Two predicates can be combined with and or or:
The operators are case insensitive. Any other word is rejected with an XmlDbException ("Invalid XPath syntax").
Positions are always evaluated by the DOM XPath fallback, they are never translated into SQL.
The id of a node is stored in the db:id attribute of the node, so it can be used in a predicate as well:
In the SQL path the value is compared with the id column of the node directly, which is much faster than a comparison of the serialized attributes.
| Operator | Meaning | Evaluated by |
|---|---|---|
| = | attribute is equal to the value | SQL |
| != | attribute is not equal to the value | DOM XPath |
| < <= > >= | comparison of the attribute value | DOM XPath |
| and or | combination of two conditions | SQL |
| position(), last() | position of the node | DOM XPath |
An unknown operator raises an XmlDbException ("Invalid XPath operator").
A query is answered by the database when all of the following is true:
In that case the path is translated into a join over the node table, one joined table per level of the path, and the result is read from the database. Only the ids of the matching nodes are transferred.
In every other case the query is answered by the DOM XPath engine: the document is loaded into a DOMDocument and the query is executed there. The ids are read back from the db:id attributes of the matched nodes.
The fallback is transparent, the result is the same. It is, however, much slower, because the whole document has to be loaded. Prefer queries that can be answered by the database, especially for large documents.
The dialect is a subset of XPath 1.0. The following is not supported:
Namespace wildcards (*:name, *g:f*) are an XPath 2.0 syntax. They work in the SQL path, but they cannot be verified with the DOM XPath engine of PHP, which only knows XPath 1.0.
The values of the matched nodes can also be resolved directly, without building a DOM, see the Indexer.