0

我有以下 xml 文档:

<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 中构建一个额外的循环来循环每个缩进的产品

说得通?

4

2 回答 2

1

我会不用xpath,只使用两个嵌套foreach的循环:

$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

顺便说一句:您的 XML 已损坏,可能是拼写错误。每个结束</price>都缺少最后一个>

于 2013-10-25T23:21:34.647 回答
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 中的实际路径可以访问父元素(另请参阅:使用 PHP 的 SimpleXML 访问元素的父元素? )。然后读取两个属性,然后通过 PHP 5.4 数组取消引用第一个(也是唯一一个)属性。

我希望这会有所帮助并阐明它是如何工作的。你的问题让我想起了之前的一个问题,我为这些问题提出了一些通用的解决方案:

于 2013-10-26T21:29:21.260 回答