You can use the ancestor-axis to fetch this path.
The Fully-Fledged Xpath 2.0 Solution
This will return a path for the current element. More on this solution in my answer to a similar question where XPath 2.0 was fine. If you append //*[@special="yes"]/
, it will return all pathes for the "special" elements.
string-join(
(
'',
(
.//ancestor-or-self::*/name(),
concat("@", .//ancestor-or-self::attribute()/name())
)
),
'/'
)
You can remove all newlines if you prefer, but it's easier to understand when nicely wrapped.
Getting Your Hands Dirty
Sadly, PHP does not support XPath 2.0 out-of-the-box and you will have to do the looping and concatenation stuff in PHP, but still can use the ancestor-axis.
Building upon @Rolando Isidoro solution, this will make the "main" loop of his code both more elegant and efficient (although the improvement is minor and probably only noticeable in very large documents with very deep structure):
foreach ($nodes as $node) {
$breadcrumbs[$nodeCount] = array();
// Returns all nodes on ancestor path in document order
foreach ($node->xpath('ancestor-or-self::*') as $axisStep) {
// So all we need to do is append the name at the end of the array
$breadcrumbs[$nodeCount][] = $axisStep->getName();
}
$nodeCount++;
}