0

Is there a way to perform an xpath query on a DOMNodeList obtained by a previous xpath query? Concretely, I have the following code:

$topicMap = new DOMDocument();
$topicMap->load('topicMap.xml');
$xpath = new DOMXpath($topicMap);
$relations = $xpath->query("/topicMap/relations");

Now, from the resulting DOMNodelist $relations, I would like to select various subsets, depending on the @type attribute of the relations elements. I tried to supply the DOMNodeList as a second argument (i.e., context node) to a second xpath query, like so:

$relations_translation = $xpath->query("/*[@type='translation']", $relations)

I am receiving the following error: Argument 2 passed to DOMXPath::query() must be an instance of DOMNode, instance of DOMNodeList given.

I know that I could perform the two queries in one step, i.e., $relations_translation = $xpath->query("/topicMap/relations[@type='translation']"). The reason why I would like to do it in two steps is performance. The xml document topicMap.xml is very large, the set of relations elements a small part of it, and the number of queries that I need to perform on this set also relatively large. So I am thinking that it will be faster to traverse the large xml document only once, select the relations elements, and then perform the various queries on this much smaller list of nodes. I don't know yet whether it will be faster, but I would like to try. Is there a way to do what I want to do?

Thanks in advance for your help!

Wolfhart
  • 49
  • 6
  • 3
    You will need to loop on the returned domlist. Also , use a relative search the second time : .[@type=… . – Ptit Xav Feb 27 '22 at 22:10
  • @PtitXav: Thanks for the quick reply! I thought about looping through the DOMNodelist, but see the following problem with this approach: I need the `relations` of a certain `@type` as a DOMNodelist which I can, then again, loop through and process. And I don't see how, by looping through the original DOMNodeList, I can collect a certain subset of it in a DOMNodelist. – Wolfhart Feb 27 '22 at 22:37
  • [this post](https://stackoverflow.com/questions/27200556/how-to-add-elements-to-domnodelist-in-php) may help you – Ptit Xav Feb 28 '22 at 08:24

1 Answers1

0

Following the suggestion by Ptit Xav, I came up with the following solution:

$topicMap = new DOMDocument();
$topicMap->load('topicMap.xml');
$xpath = new DOMXpath($topicMap);
$relations = $xpath->query("/topicMap/relation");

$translations = array(); // and analogously for other types of relation
foreach ($relations as $item) {
   if ($item->getAttribute("type") == "trans") {
      $translations[] = $item; 
   }
   // and analogously for other types of relation
}

That is, I loop through the $relations, check for the @type attribute and then store the relations according to their type in predefined arrays.

Wolfhart
  • 49
  • 6