我有以下 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"和"名称")。
我可以轻松地将我的 xpath 更改为从商店而不是产品开始,但我不确定最有效的方法是在我的 foreach 中构建一个额外的循环来循环每个缩进的产品
有意义?
我会不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>
都缺少其最后>
。
当然,这是有道理的,你想要一次迭代,而不是迭代的嵌套产品(尽管这不会削减你太多,@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 数组取消引用第一个(也是唯一的)属性被访问。
我希望这有所帮助并阐明它是如何工作的。你的问题让我想起了之前的一个问题,我提出了针对这类问题的某种通用解决方案:
- 将两个 Xpath 合并为一个循环的答案?