2012-10-26 96 views
3

我有一塊XML,其中相同的信息可以作爲不同節點的子項出現。如:使用xpath選擇第一個結果的子項

<root> 
<category id=1> 
     <product id="ABC123" > 

       <sizes> 
        <size name="S"/> 
       <size name="M"/> 
       <size name="L"/> 
       <size name="XL"/> 
       <size name="2XL"/> 
       <size name="3XL"/> 
       </sizes> 
      </product> 

       </products> 
      </category> 
<category id=2> 
     <products> 
     <product id="ABC123" > 

       <sizes> 
        <size name="S"/> 
       <size name="M"/> 
       <size name="L"/> 
       <size name="XL"/> 
       <size name="2XL"/> 
       <size name="3XL"/> 
       </sizes> 
      </product> 

      <product id="PPP543" > 

       <sizes> 
        <size name="S"/> 
       <size name="M"/> 
       <size name="L"/> 
       <size name="XL"/> 
       </sizes> 
      </product> 

       </products> 
      </category> 

我的目標是選擇產品ID ABC123的大小,並將它們存儲爲一個數組。我現有的代碼是:

$arrTest=array(); 


    foreach($xml->xpath('//root/category/products/product[@id= "'.$productCall.'" ]/sizes/size') as $size){ 

       array_push($arrTest, $size["name"]); 
     } 

$ productCall是我正在查找的ID。在這種情況下,它是ABC123。輸出爲S,M,L,XL,2XL,3XL,S,M,L,XL,2XL,3XL。這意味着它正在讀取找到的兩個條目。我期望這給foreach循環,但我似乎無法找到一種方式來獲得第一個結果的輸出。我曾嘗試添加[0]和[1]:

$y=$xml->xpath('//root/category/products/product[@id= "'.$productCall.'" ][1]/sizes/size'); 

[0]沒有返回和[1]返回我已經得到了相同的結果。

我希望這是一個簡單的事情,我錯過了一些基本的東西或只是過度思考,因爲我真的沒有用過xpath之前。

回答

0

使用

(/*/*//product[@id='ABC123']/sizes)[1]/size 

或者使用

((/*/*/product | /*/*/products/product)/sizes)[1]/size 

XSLT - 基於驗證

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "(/*/*//product[@id='ABC123']/sizes)[1]/size"/> 
======== 
    <xsl:copy-of select= 
    "((/*/*/product | /*/*/products/product)/sizes)[1]/size"/> 

</xsl:template> 
</xsl:stylesheet> 

當該變換被應用到所提供的XML文檔(校正成一個結構良好的一個後):

<root> 
    <category id="1"> 
     <product id="ABC123" > 
      <sizes> 
       <size name="S"/> 
       <size name="M"/> 
       <size name="L"/> 
       <size name="XL"/> 
       <size name="2XL"/> 
       <size name="3XL"/> 
      </sizes> 
     </product> 
    </category> 
    <category id="2"> 
     <products> 
      <product id="ABC123" > 
       <sizes> 
        <size name="S"/> 
        <size name="M"/> 
        <size name="L"/> 
        <size name="XL"/> 
        <size name="2XL"/> 
        <size name="3XL"/> 
       </sizes> 
      </product> 
      <product id="PPP543" > 
       <sizes> 
        <size name="S"/> 
        <size name="M"/> 
        <size name="L"/> 
        <size name="XL"/> 
       </sizes> 
      </product> 
     </products> 
    </category> 
</root> 

兩個的XPath表達式,並且從每一個所選擇的節點,以及在視覺上界定,被複制到輸出 - 無論是正確

<size name="S"/> 
<size name="M"/> 
<size name="L"/> 
<size name="XL"/> 
<size name="2XL"/> 
<size name="3XL"/> 
======== 
    <size name="S"/> 
<size name="M"/> 
<size name="L"/> 
<size name="XL"/> 
<size name="2XL"/> 
<size name="3XL"/> 

請注意:我預計第二XPath表達式更有效率(上足夠大的文件),因爲它不使用//僞操作符。

+0

謝謝您的詳細回覆!這正是我需要的。只是爲了澄清,第二個表達式以'(('我可以看到一個'關閉')'開頭,它清楚地起作用(和需要)以正常工作。你能解釋爲什麼這樣,或者指向一個資源那麼可以嗎?再次感謝! –

+0

糟糕 - 我看到其他的關閉了,現在有更多的意義了! –

+0

@SarahChen,不用客氣,括號是覆蓋'[]'操作符的優先級高於'''僞操作符。 –