2013-10-25 57 views
0

我有以下XML文檔:Xpath的循環查詢

<shop id="123" name="xxx"> 
    <product id="123456"> 
    <name>Book</name> 
    <price>9.99</price 
    </product> 
    <product id="789012"> 
    <name>Perfume</name> 
    <price>12.99</price 
    </product> 
    <product id="345678"> 
    <name>T-Shirt</name> 
    <price>9.99</price 
    </product> 
</shop> 
<shop id="456" name="yyy"> 
    <product id="123456"> 
    <name>Book</name> 
    <price>9.99</price 
    </product> 
</shop> 

我有以下的循環來收集每個產品的信息:

$data_feed = 'www.mydomain.com/xml/compression/gzip/'; 
$xml = simplexml_load_file("compress.zlib://$data_feed"); 

     foreach ($xml->xpath('//product') as $row) { 
         $id = $row["id"]; // product id eg. "123456" 
         $name = $row->name; 
         $price = $row->price; 

     // update database etc. 
     } 

不過,我也希望收集的信息每個產品的母店(「id」和「name」)。

我可以很容易地改變我的XPath從店鋪開始,而不是產品,但我不能確定的最有效的方法,然後構建我的foreach內的附加循環以各縮進產品

有意義嗎?

回答

1

我去無xpath和只使用兩個嵌套foreach -loops:

$xml = simplexml_load_string($x); // assume XML in $x 

foreach ($xml->shop as $shop) { 
    echo "shop $shop[name], id $shop[id] <br />"; 
    foreach ($shop->product as $product) { 
     echo "- $product->name (id $product[id]), $product->price <br />"; 
    } 
} 

看到它的工作:http://codepad.viper-7.com/vFmGvY

BTW:你的XML壞了,可能是一個錯字。每個收盤價</price>缺失其最後的>

+0

我會同意這種看法。無論如何,如果您需要迭代每個節點,我都不會看到XPath爲您提供了什麼。 –

0

當然是有道理的,你想一個迭代,而不是重複的嵌套產品(雖然不會砍你了,@michi顯示的話),這是可能的:

foreach ($xml->xpath('//product') as $row) 
{ 
    $id  = $row["id"]; // product id eg. "123456" 
    $name  = $row->name; 
    $price = $row->price; 
    $shopId = $row->xpath('../@id')[0]; 
    $shopName = $row->xpath('../@name')[0]; 

    // update database etc. 
} 

由於此示例顯示,您可以在每個元素節點上運行xpath(),並且上下文節點自動設置爲節點本身,因此xpath中的實際路徑..可用於訪問父元素(請參閱:Access an element's parent with PHP's SimpleXML?)。然後讀取這兩個屬性,然後通過PHP 5.4數組取消引用第一個(也是唯一的)屬性。

我希望這可以幫助並闡明它是如何工作的。你的問題讓我想起了一下較早的一個,我建議某種通用的解決方案對這些類型的問題: