如何在 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-&gt;getElementsByTagName("CODE") 是不可能的,因为我不知道正确的一个CODE 节点的订单ID。我尝试过使用 XPATH,但我完全迷路了,不知道如何构造查询以仅获取 SHOP > SHOPITEM > CODE 中的 CODE 值以及SHOP &gt; SHOPITEM &gt; RELATED_PRODUCTS &gt; CODEFLAG &gt; CODE 或@987654325 中的所有其他值@ ...如何排除这些或更好地要求正确的?

【问题讨论】:

好吧,XPath 语法使用/ 来分隔步骤,而不是&gt;,但除此之外,您的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 获取最近的子节点而不是嵌套的子节点的主要内容,如果未能解决你的问题,请参考以下文章

如何在WebElement中通过xpath查找子元素

如何使用 php 从 HTML 表中提取数据

XPath如何定位dom节点

如何使用DOM4j+xpath 解析

php 8 中的 xpath 如何处理?

DOM 与 XPath - 区别? [关闭]