2017-01-16 91 views
0

我想使用xpath表達式替換foreach循環,但我需要一個DOMXPath對象返回多個列表。用XPath表達式替換foreach循環使用DOMXPath

我有以下XML(簡體),我使用DOMDocumentDOMXPath遍歷它:

<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> 

我想通過RPH數分割房間,創建每個RPH房間列表。目前,我使用下面的代碼:

//$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; 
} 

這是現在工作,但我想用Xpath表達式替換foreach循環。我可以使用表達式$rooms = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room[a:RPH='{$rph}']");$rph是一個數字,但如果我不知道RPH(它可能是0到99之間的任何值),我該怎麼做。可能嗎?

總之,有沒有辦法用XPath替換我的foreach循環?

我在想使用registerPhpFunctions和一個自定義功能,但我關注這個方法的性能與foreach循環

+1

不,你仍然需要一個'foeach'。您必須迭代房間以創建嵌套結果或可能的$ rph值來獲取組。 – ThW

+0

感謝您的評論。所以,我原來的做法是正確的。如果你願意,我會爲任何改進的新想法保留這個問題,但你可以發表你的評論作爲答案。如果我沒有收到任何新建議,我會將其標記爲正確。 – James

回答

1

的XPath 1.0表達式將返回一個節點列表相比,他們可以在一定程度上拉平一個現有的結構,如果您使用的軸類似於descendantancestor,但它將是一個節點列表。它不能分組或聚合它們。

您可以獲取具有特定RPH值的節點列表。但是你需要爲每個值設置這個值,結果會是另一個循環。這意味着要獲取所有RPH值,使它們唯一,對它們進行迭代並對每個值執行Xpath表達式。

您目前的解決方案很好。