簡體   English   中英

PHP中的Xpath與OTA標准

[英]Xpath in PHP with OTA standards

我有關於在PHP中使用Xpath的基本知識,但我遇到了一些特定情況的麻煩,我認為問題出在標准中。

這是XML的片段,它基於OTA標准

<SendHotelResResult xmlns:a="http://schemas/Models/OTA" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <a:RoomRates>
         <a:RoomRate>
             <a:EffectiveDate>2015-11-13T00:00:00</a:EffectiveDate>
             <a:ExpireDate>2015-11-15T00:00:00</a:ExpireDate>
             <a:RatePlanID>25</a:RatePlanID>
             <a:RatesType>
                 <a:Rates>
                     <a:Rate>
                         <a:AgeQualifyingCode i:nil="true"/>
                                 <a:EffectiveDate>2015-11-13T00:00:00</a:EffectiveDate>
                         <a:Total>
                             <a:AmountAfterTax>0</a:AmountAfterTax>
                             <a:AmountBeforeTax>260.00</a:AmountBeforeTax>
                             <a:CurrencyCode>EUR</a:CurrencyCode>
                          </a:Total>
                     </a:Rate>
                     <a:Rate>
                         <a:AgeQualifyingCode i:nil="true"/>
                             <a:EffectiveDate>2015-11-14T00:00:00</a:EffectiveDate>
                         <a:Total>
                             <a:AmountAfterTax>0</a:AmountAfterTax>
                             <a:AmountBeforeTax>260.00</a:AmountBeforeTax>
                             <a:CurrencyCode>EUR</a:CurrencyCode>
                         </a:Total>
                     </a:Rate>
                 </a:Rates>
             </a:RatesType>
             <a:RoomID>52</a:RoomID>
             <a:Total>
                 <a:AmountAfterTax>546.00</a:AmountAfterTax>
                 <a:AmountBeforeTax>520.00</a:AmountBeforeTax>
                 <a:CurrencyCode>EUR</a:CurrencyCode>
             </a:Total>
         </a:RoomRate>
     </a:RoomRates>
</SendHotelRes>

我想要的

  1. 根據元素<RoomID>獲取特定的<RoomRate>標記。
  2. 獲取全局RoomRate <Total>標記。 我不想要<Rate>標簽內的<Rate> <Total> <Rate>標簽。 這就是我使用xpath而不是簡單的getElementsByTagName('Total') 我不知道OTA標准是否有一些區分Total標簽的方法。

我的嘗試到現在為止:

$dom = new DOMDocument();
$response = $dom->load($xmlSendHotelRes);
$roomID = '52';
$roomRatesTag = $response->getElementsByTagName('RoomRates')->item(0);
$prefix = $roomRatesTag->prefix;
$namespace = $roomRatesTag->lookupNamespaceURI($prefix);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace($prefix, $namespace);
$roomRateTotal = $xpath->query("//RoomRate[RoomID=$roomID]/Total", $roomRatesTag, true);

我已嘗試使用和不使用$roomRatesTag作為上下文以及其他表達式,例如: ./RoomRate[RoomID=$roomID]/Total //RoomRate[RoomID=$roomID]/Total//RoomRate/[RoomID=$roomID]/Total //RoomRate[RoomID=$roomID]/Total//RoomRate/[RoomID=$roomID]/Total//RoomRate[RoomID=$roomID]/Total//RoomRate/RoomID[text() = $roomID]/../Total但其中任何一個都有效。

實際上,甚至$roomRate = $xpath->query("//RoomRate"); 返回一個空的DOMNodeList,所以,我不知道我做錯了什么,我正在考慮標准中的問題,在不同的地方有2個相同的標簽,雖然這沒有多大意義。

還有其他一些我需要嘗試的表達方式嗎?

您正在從文檔中獲取命名空間。

$prefix = $roomRatesTag->prefix;
$namespace = $roomRatesTag->lookupNamespaceURI($prefix);

但這不是必要的,也不是一個好主意。 您知道該文檔使用OTA,因此您知道命名空間是http://schemas/Models/OTA

前綴只是實際命名空間值的別名,以下3個XML示例都解析為節點{http://schemas/Models/OTA}RoomRates

  • <a:RoomRates xmlns:a="http://schemas/Models/OTA"/>
  • <ota:RoomRates xmlns:ota="http://schemas/Models/OTA"/>
  • <RoomRates xmlns="http://schemas/Models/OTA"/>

您的Api必須在命名空間內查找節點。

一種可能性是使用*NS (名稱空間感知)方法。

$response->getElementsByTagNameNS('http://schemas/Models/OTA', 'RoomRates')->item(0);

另一種是使用Xpath並為命名空間注冊前綴。 這可以是文檔中的前綴,也可以是不同的前綴。

$document = new DOMDocument();
$document->load($xmlSendHotelRes);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('ota', 'http://schemas/Models/OTA');

var_dump(
  $xpath->evaluate(
    'string(//ota:RoomRates/ota:RoomRate[ota:RoomID=$roomID]/ota:Total)')
  )
);

對於位置路徑, DOMXpath::evaluate()將返回DOMNodeList但是使用string()將第一個找到的節點轉換為字符串並返回它。

你需要使用一個前綴(你注冊的),我想你想用.//開始你的路徑而不是//如果你想要相對於上下文節點進行搜索,那么試試".//a:RoomRate[a:RoomID=$roomID]/a:Total"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM