'PHP DOM perform xpath query on DOMNodeList
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!
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Wolfhart |
