Php 选定节点内的SimpleXML xpath
我有以下XML文件Php 选定节点内的SimpleXML xpath,php,xml,xpath,simplexml,Php,Xml,Xpath,Simplexml,我有以下XML文件 <Item> <name>...</name> <id>...</id> <ImageSets> <ImageSet Category="variant"> <SwatchImage> <URL>...</URL> <Height Units="pixels"><
<Item>
<name>...</name>
<id>...</id>
<ImageSets>
<ImageSet Category="variant">
<SwatchImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SwatchImage>
<SmallImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SmallImage>
</ImageSet>
<ImageSet Category="primary">
<SwatchImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SwatchImage>
<SmallImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SmallImage>
</ImageSet>
</ImageSets>
</Item>
<Item>....</Item>
等等。代码可以完美地提取每个项目的名称和Id
现在我的问题是提取ImageSet Category='primary'->SmallImage->URL。ImageSet节点不按任何特定顺序排列,因此有时“主”将是第一个,有时是“变体”,这就是为什么$item->ImageSet->ImageSet[1]
不是解决方案的原因
因此,在我的主foreach循环中,我尝试使用xpath,如下所示:
$src='';
foreach ($item->ImageSets->xpath('//ImageSet[@Category="primary"]') as $img){
$src = $img->MediumImage->URL;
};
绝对没有运气
如果您有任何想法,我们将不胜感激。与您的上下文节点$item相关(我毫不怀疑这就是您需要该上下文节点的原因;-))您正在寻找的图像集a)是图像集的子级(而图像集又是您上下文节点的直接子级),b)具有值为
primary
(您已正确编码)
与您的上下文节点相关$item(毫无疑问,这就是您需要该上下文节点的原因;-))您正在寻找的图像集a)是图像集的子级(而图像集又是您上下文节点的直接子级),b)具有值为primary
(您已正确编码)的属性类别
XPath表达式中存在错误。如果表达式以/
开头,则它是相对于文档本身的。您希望它相对于当前节点。这意味着您有两种可能的解决方案
ImageSet[@Category=“primary”]
这将扩展到child::ImageSet
。它获取作为上下文节点直接子节点的ImageSet
元素节点
//ImageSet[@Category=“primary”]
展开并规范化为子体::图像集
。它获取当前上下文中的任何ImageSet
,即使它不是直接子级。
表示当前节点,并且/
将轴更改为子体。XPath表达式中存在错误。如果表达式以/
开头,则它是相对于文档本身的。您希望它相对于当前节点。这意味着您有两种可能的解决方案
ImageSet[@Category=“primary”]
这将扩展到child::ImageSet
。它获取作为上下文节点直接子节点的ImageSet
元素节点
//ImageSet[@Category=“primary”]
展开并规范化为子体::图像集
。它获取当前上下文中的任何ImageSet
,即使它不是直接子级。
表示当前节点,并且/
将轴更改为子节点。太棒了,hovewer我找到了另一个:foreach($item->ImageSet->ImageSet as$img){foreach($img->attributes()as$a=>$b){if($b='primary'){$src=$img->MediumImage->URL;echo$src;}}; 只是想知道哪一个会更快?性能->不要猜测,而是测量。但是我有一个预感,不在脚本中进行迭代和比较会更快。很好的说明,霍韦弗我找到了另一个:foreach($item->ImageSet->ImageSet as$img){foreach($img->attributes()as$a=>$b){if($b='primary'){$src=$img->MediumImage->URL;echo$src;};只是想知道哪一个会更快?性能->不要猜测,而是测量。但我有一种预感,不在脚本中进行迭代和比较会更快。
$src='';
foreach ($item->ImageSets->xpath('//ImageSet[@Category="primary"]') as $img){
$src = $img->MediumImage->URL;
};
<?php
$itemset = new SimpleXMLElement(data());
foreach ($itemset as $item) { // or something else - just some reason why you have to work with $item
foreach ($item->xpath('ImageSets/ImageSet[@Category="primary"]') as $p) {
echo $p->SwatchImage->URL;
}
}
function data() {
return <<< eox
<ItemSet>
<Item>
<name>...</name>
<id>...</id>
<ImageSets>
<ImageSet Category="variant">
<SwatchImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SwatchImage>
<SmallImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SmallImage>
</ImageSet>
<ImageSet Category="primary">
<SwatchImage>
<URL>primary swatch image url</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SwatchImage>
<SmallImage>
<URL>...</URL>
<Height Units="pixels"></Height>
<Width Units="pixels"></Width>
</SmallImage>
</ImageSet>
</ImageSets>
</Item>
<Item>...</Item>
</ItemSet>
eox;
}