2009-11-13 69 views
1

我以下面的格式給出XML,並使用PHP的SimpleXML解析它。企圖炫耀在每個房間的乘客(人)的姓名PHP SimpleXML XPath包含()以查找此元素引用的其他元素

// $Accommodation is a SimpleXML Object defined earlier, and able to provide relevant info 
<? foreach ($Accommodation->Units as $Units) { 
     foreach ($Units->Unit as $Unit) { 
     // (room/unit details echoed out here) 
      foreach ($Unit->xpath('//Passenger[contains(PaxAssociated,./PaxNo)]') as $RoomPax) { ?> 
<?= $RoomPax->Title $RoomPax->Surname" ?><br /> 
<?= "$RoomPax->Title $RoomPax->Surname" ?><br /> 
<?   } 
     } 
    } ?> 

<?xml version="1.0" encoding="UTF-8"?> 
<ManageMyBooking> 
    <BookingInfo> 
     <PartyDetails> 
      <Passenger> 
       <PaxNo>1</PaxNo> 
       <Title>Mrs</Title> 
       <Surname>Murphy</Surname> 
      </Passenger> 
      <Passenger> 
       <PaxNo>2</PaxNo> 
       <Title>Mr</Title> 
       <Surname>Murphy</Surname> 
      </Passenger> 
      <Passenger> 
       <PaxNo>3</PaxNo> 
       <Title>Miss</Title> 
       <Surname>Murphy</Surname> 
      </Passenger> 
     </PartyDetails> 
     <Accommodation> 
      <Units> 
       <Unit> 
        <UnitNo>1</UnitNo> 
        <UnitDesc>...</UnitDesc> 
        <PaxAssociated>1|2</PaxAssociated> 
       </Unit> 
       <Unit> 
        <UnitNo>2</UnitNo> 
        <UnitDesc>...</UnitDesc> 
        <PaxAssociated>3</PaxAssociated> 
       </Unit> 
      </Units> 
     </Accommodation> 
    </BookingInfo> 
</ManageMyBooking> 

我循環通過單位(室),因此。

但是這個xpath找不到任何人,下面會得到所有人。

//Passenger[contains(PaxNo,./PaxAssociated)] 

什麼特別令人沮喪的是,我已經成功地使用XPath的其他地方一樣PHP的一個非常相似的目的,沒有任何問題。

任何幫助/意見/建議將不勝感激。


編輯: 的完整性,並回答多的人一個問題:在代碼中的其他地方 下面的作品,(雖然不是100%正確地給出VS「2」「22」的可能匹配。

//Flight[contains(PaxAssociated,./PaxNo)] 
+0

我很困惑一個元素上的xpath如何返回'//乘客'的任何結果,因爲在您的示例x​​ml結構中,單元不包含乘客。你可以發佈如何定義$ accomodation對象嗎? – 2009-11-13 12:52:32

+0

它似乎是SimpleXML對象的內置功能,Unit元素直接創建了一個包含整個樹的SimpleXML對象。 – jezmck 2009-11-13 13:40:51

+0

有趣的功能 - 很好的瞭解這一點,謝謝! – 2009-11-13 13:51:08

回答

3

此:

//Passenger[contains(PaxNo,./PaxAssociated)] 

是:找到與孩子<PaxNo>誰的價值的任何<Passenger>包含孩子的價值<PaxAssociated>。它只會與這樣的數據結構(你顯然沒有):

<ManageMyBooking> 
    <BookingInfo> 
    <PartyDetails> 
     <Passenger> 
     <PaxNo>1|2</PaxNo> <!-- note the exchanged value! --> 
     <PaxAssociated>1</PaxAssociated> 
     </Passenger> 
    </PartyDetails> 
    </BookingInfo> 
</ManageMyBooking> 

所以這是錯誤的多個帳戶。你什麼意思可能是一個動態的XPath表達式,如:

foreach ($Units->Unit as $Unit) { 
    $XPath = "//Passenger[contains('". $Unit->PaxAssociated . "', PaxNo)]"; 
    foreach ($Unit->xpath($XPath) as $RoomPax) { 
    // ... 
    } 
} 

這部作品乍看之下,但它不是萬無一失,因爲「22」包含「2」爲好。所以單獨做一個不會讓你任何地方。正確的將是:

$XPath = "//Passenger[contains('|". $Unit->PaxAssociated ."|', concat('|', PaxNo, '|'))]"; 

這樣你檢查「| 22 |」反對「| 2 |」,這將返回false。

+1

最後一個代碼片段中有一個小的錯字,應該是'contains('|'(倒數最後兩個字符) – 2009-11-13 13:08:23

+0

Whhops。當然,感謝您的注意。:-) – Tomalak 2009-11-13 13:09:54

+0

同樣的問題在這裏:在$ unit對象上運行時,'// passenger ...'的xpath怎麼會返回任何東西(除非$ unit會*不*對應於標記中的)? – 2009-11-13 13:28:17

相關問題