Philip
Philip

Reputation: 3799

Selecting Nodes using xPath with unions

I'm writing a basic HTML report templating system based on manipulating the data using xPath. Essentially, I need an xPath query which will select a node OR its children if they have a certain class.

$query = $xPath->query (".//*[contains(concat(' ', normalize-space(@class), ' '), ' -delete-if-no-stock ')]", $node);

I understand that the xPath selector .//*[contains(concat(' ', normalize-space(@class), ' '), ' -delete-if-no-stock ')] is specifically looking at descendant nodes of the $node parameter.

I would like an xPath query that essentially asks "the node or any of its children". I know that there is a union operator, |, but I haven't seen how to implement that. I would have imagined something like this: .[contains(concat(' ', normalize-space(@class), ' '), ' -delete-if-no-stock ')] | .//*[contains(concat(' ', normalize-space(@class), ' '), ' -delete-if-no-stock ')] but this generates an Invalid expression error.

Upvotes: 0

Views: 3065

Answers (2)

ThW
ThW

Reputation: 19512

Xpath expressions work as filters. They do not aggregate/compile in that kind of sense (Like an SQL Union).

Here are several possibilities depending on what you're trying to do.

Alternative Expressions

The pipe symbol | allows you to specify multiple expressions - it works like the comma , in CSS selectors.

expression_one|expression_two

Complex conditions

Conditions in the expressions can use and and or as well as brackets.

/location/path[condition and condition or condition]

Axis

Xpath expressions have a concept of axis that define the initial set of nodes the filter is applied to.

axis::node[condition]

.//* is short for self::node()/descendant::*. Here is a axis called descendant-or-self that includes the current node and all descendants.

descendant-or-self::*[contains(...)]

Upvotes: 1

Phil Blackburn
Phil Blackburn

Reputation: 1067

Try using an axis operator...

descendant-or-self::node()[contains(concat(' ', @class, ' '), ' -delete-if-no-stock ')]

Upvotes: 0

Related Questions