XPathQuery Class

XPathQuery extracts data from XML documents using XPath expressions. It has methods for a value, for a list of values, for a structure and for the DOM nodes, parameters that are quoted for you, context nodes and support for namespaces.

Basic Usage

use Derafu\Xml\XPathQuery;

// Initialize with an XML string, an XmlDocument or a DOMDocument.
$query = new XPathQuery($xmlString);

// Get a single value.
$value = $query->getValue('/root/element');

// Get multiple values.
$values = $query->getValues('/root/items/item');

// Get DOM nodes.
$nodes = $query->getNodes('/root/items/item');

// Get structured data.
$data = $query->get('/root');

An XML string that is not well formed throws an XmlParseException when the query is created. A query that fails throws an XmlQueryException (see Exceptions).

What Each Method Returns

Method Returns
getValue($query) The value of the first node, as a string, or null if there is none.
getValues($query) A list with the value of each node. A node without value is null.
getNodes($query) A DOMNodeList with the nodes.
get($query) The structure of what the query finds, as the next section says.

The Structure That get() Returns

  1. null if no node is found.
  2. A string if a node that has only text is found (an element without content is an empty string; an attribute is its value).
  3. An array if the node has child elements: the value of each child by its name, and a list for the elements that are repeated.
  4. A list of those, if several nodes are found.

It is the simple structure of the document: the attributes, the namespaces and the comments are not in it. For all of the XML use the decoder (see Array Structure).

For this XML:

<root>
  <person>
    <name>John</name>
    <age>30</age>
  </person>
  <person>
    <name>Jane</name>
    <age>25</age>
  </person>
</root>

The query $query->get('/root/person') returns:

[
    ['name' => 'John', 'age' => '30'],
    ['name' => 'Jane', 'age' => '25'],
]

And $query->get('/root/person[1]/name') returns 'John'.

Parameterized Queries

The values that go in a query are given as parameters: in the query the parameter is written :name, and in the array of parameters it is name. They are quoted for you, also when they have quotes:

$result = $query->get('//item[@id=:id and @type=:type]', [
    'id' => '123',
    'type' => 'product',
]);

$params = ['complex' => 'Value with "double" and \'single\' quotes'];
$result = $query->get('//element[text()=:complex]', $params);

Context Nodes

get(), getValue(), getValues() and getNodes() take a context node as the last parameter, to query from it:

// Get a context node.
$contextNode = $query->getNodes('//section')->item(0);

// Query within that context.
$result = $query->get('./item', [], $contextNode);

Working with Namespaces

By default the namespaces are ignored: the names in the query match the elements by their local name, whatever their namespace and prefix.

$xml = '<r xmlns="urn:d" xmlns:p="urn:p"><p:a>1</p:a><b>2</b></r>';

$query = new XPathQuery($xml);
$query->get('//a'); // "1": the element p:a, found by its name.
$query->get('//b'); // "2"

With the namespaces of the query as the second parameter they are used as the XPath says: the names have the prefix of the namespace that they are in.

$namespaces = ['d' => 'urn:d', 'p' => 'urn:p'];
$query = new XPathQuery($xml, $namespaces);

$query->get('//p:a'); // "1"
$query->get('//d:b'); // "2"
$query->get('//b');   // null: b is in the namespace urn:d, it is not a name without namespace.

The prefixes are the ones that you give, not the ones that the document uses: they can be different. It is the way to query a document whose prefixes you do not control.

Without registering the namespaces a name with a prefix (//p:a) is not valid.

Querying an XmlDocument

An XmlDocument can be given instead of a string. Also the one that the encoder gives:

$document = $encoder->encode($data);

$query = new XPathQuery($document, ['cbc' => 'urn:example:basic']);
$query->get('//cbc:ID');

XmlDocument::query() and getNodes() use XPathQuery without namespaces.

Error Handling

use Derafu\Xml\Exception\XmlQueryException;

try {
    $result = $query->get('//invalid[xpath');
} catch (XmlQueryException $e) {
    echo $e->getMessage();
    // An error occurred while executing the XPath expression: ... Invalid predicate.
}
On this page

Last updated on 30/10/2026 by Anonymous