如何在 PHP 中使用 DOM 或 XPATH 获取最近的子节点而不是嵌套的子节点
Posted
技术标签:
【中文标题】如何在 PHP 中使用 DOM 或 XPATH 获取最近的子节点而不是嵌套的子节点【英文标题】:How to get nearest child node and not the nested ones using DOM or XPATH in PHP 【发布时间】:2021-10-21 07:49:55 【问题描述】:有一些这样的 XML 产品提要:
<SHOP>
<SHOPITEM id="2927" import-code="PREMIER">
<NAME>productname</NAME>
<DESCRIPTION>Blah, blah, blah ...</DESCRIPTION>
<RELATED_PRODUCTS>
<CODE>PXP-01-01</CODE>
<CODE>PXP-01-02</CODE>
<CODE>PXP-01-03</CODE>
</RELATED_PRODUCTS>
<FLAGS>
<FLAG>
<CODE>news</CODE>
<ACTIVE>1</ACTIVE>
</FLAG>
<FLAG>
<CODE>action</CODE>
<ACTIVE>0</ACTIVE>
</FLAG>
</FLAGS>
<CODE>PXS-01-MNCRFT</CODE>
<EAN>0702811692053</EAN>
<WEIGHT>0.5</WEIGHT>
<PRICE>123</PRICE>
<VAT>21</VAT>
</SHOPITEM>
</SHOP>
并且需要在 php 循环中获取产品代码。看起来很简单,但使用$item->getElementsByTagName("CODE")
是不可能的,因为我不知道正确的一个CODE 节点的订单ID。我尝试过使用 XPATH,但我完全迷路了,不知道如何构造查询以仅获取 SHOP > SHOPITEM > CODE 中的 CODE 值以及SHOP > SHOPITEM > RELATED_PRODUCTS > CODE
或FLAG > CODE
或@987654325 中的所有其他值@ ...如何排除这些或更好地要求正确的?
【问题讨论】:
好吧,XPath 语法使用/
来分隔步骤,而不是>
,但除此之外,您的SHOP/SHOPITEM/CODE
路径表达式会选择一个特定的CODE
元素而不是其他元素。
这里有这样的,但似乎效果不好。 $query = "//SHOP/SHOPITEM[CODE[1]='$b2bCode']/PRICELISTS/PRICELIST[position()=" . $priceList . "]/STANDARD_PRICE";
如果输入样本不包含任何此类 PRICELISTS
元素,不知道如何判断为什么 XPath 中的 PRICELISTS
不起作用。或许可以使用与表达式匹配的输入来编辑问题的示例,并告诉我们您想要的结果以及您的 PHP 代码的外观。
您是否按照建议尝试了 XPath SHOP/SHOPITEM/CODE
?
【参考方案1】:
使用xpath,这样试试
$dom = new DOMDocument();
$dom->loadXML($xml_string);
$xpath = new DOMXPath($dom);
$flags = $xpath->query('//SHOPITEM//FLAGS');
foreach ($flags as $flag)
foreach ($xpath->query('.//FLAG/CODE',$flag) as $target)
echo $target->nodeValue ."\n";
;
输出:
news
action
下一步:
$codes = $xpath->query('//SHOPITEM/CODE');
foreach ($codes as $code)
foreach ($codes as $code)
echo $code->nodeValue ."\n";
;
输出:
PXS-01-MNCRFT
最后:
$rps = $xpath->query('//SHOPITEM/RELATED_PRODUCTS');
foreach ($rps as $rp)
foreach ($xpath->query('.//CODE',$rp) as $target)
echo $target->nodeValue ."\n";
;
输出:
PXP-01-01
PXP-01-02
PXP-01-03
【讨论】:
以上是关于如何在 PHP 中使用 DOM 或 XPATH 获取最近的子节点而不是嵌套的子节点的主要内容,如果未能解决你的问题,请参考以下文章