kaan_atakan
kaan_atakan

Reputation: 4047

Selecting a node based on the intial context

I have an XML file with the following structure:

<r>
  <a>
    <i>
      <k>1</k>
      <d>d1</d>
    </i>
    <i>
      <k>3</k>
      <d>d3</d>
    </i>
  </a>
  <b>
    <i>
      <k>1</k>
      <d>rd1</d>
    </i>
    <i>
      <k>2</k>
      <d>id2</d>
    </i>
    <i>
      <k>3</k>
      <d>rd3</d>
    </i>
  </b>
</r>

I select the i nodes under /r/a and iterate through them to find the associated nodes under /r/b and retrieve the value of their d nodes as follows:

$data = [];
$nodes = $domXPath->evaluate('/r/a/i');
foreach($nodes as $node) {
   $key = $domXPath->evaluate('string(k)', $node);
   $data[] = $domXpath->evaluate("string(/r/b/i[k=$key]/d)", $node);
}

This produces the correct result in $data:

[
  "rd1",
  "rd3",
]

My question is whether it is possible to do this without pulling the key out to PHP so something like:

$data = [];
$nodes = $domXPath->evaluate('/r/a/i');
foreach($nodes as $node) {
   $data[] = $domXpath->evaluate("string(/r/b/i[k=initial-context()/k]/d)", $node);
}

Upvotes: 2

Views: 34

Answers (1)

Mitya
Mitya

Reputation: 34556

You can do this with a single XPath:

$nodes = $domXPath->evaluate('/r/b/i[k = /r/a/i/k]/d');
foreach($nodes as $node) $data[] = $node->textContent;

The expression says, for each /r/b/i node, allow only if its k node matches a corresponding k node under /r/a/i.

Upvotes: 3

Related Questions