简体   繁体   中英

Replace a foreach loop with XPath expression using DOMXPath

I want to replace a foreach loop using a xpath expression, but I need that a DOMXPath object to return more than one list.

I have the following XML (simplified) and I using DOMDocument and DOMXPath to iterate over it:

<a:RoomsType>
    <a:Rooms>
      <a:Room>
          <a:RPH>0</a:RPH>
      </a:Room>
      <a:Room>
          <a:RPH>1</a:RPH>
      </a:Room>
      <a:Room>
          <a:RPH>2</a:RPH>
      </a:Room>
      <a:Room>
          <a:RPH>0</a:RPH>
      </a:Room>
    <a:Rooms>
<a:RoomsType>

I want to split the rooms by the RPH number, creating a list of rooms for each RPH number. Currently, I'm using the following code:

 //$xpath is a DOMXPath object
 $roomsToIterate = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room");

 $roomList = array();
 foreach ($roomsToIterate as $room) {
     $rphCandidate = $room->getElementsByTagName("RPH")->item(0)->nodeValue;
     if (!isset($roomList[$rphCandidate])) {
         $roomList[$rphCandidate] = array();
     }
     $roomList[$rphCandidate][] = $room;
 }

This is working for now, but I want to replace the foreach loop with a Xpath expression. I can use the expression $rooms = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room[a:RPH='{$rph}']"); with $rph being a number, but how can I do it if I don't know the RPH (it could be anything between 0 and 99). Is it possible?

In short, Are there any way to replace my foreach loop using XPath?

I was thinking about the use of registerPhpFunctions and a custom function, but I concerned about the performance of this approach compared with foreach loop

Xpath 1.0 expression will return a list of nodes, they can to some extend flatten an existing structure if you use an axis like descendant or ancestor , but it will be a list of nodes. It can not group or aggregate them.

You could fetch a lists of nodes with a specific RPH value. But you would need to this for each value, the result would be another loop. This would mean to fetch all RPH values, make them unique, iterate them and execute and Xpath expression for each value.

Your current solution is fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM