PHP: xpath 或 prev() 或 for 循环?

PHP: xpath or prev() or for loop?

我在这里用头撞墙。我正在尝试遍历 XML 文件,当满足特定条件时,将节点添加到前一个元素。

我试过使用 prev() 命令,但我的研究表明无论如何这是错误的方法。我试过 xpath 命令,但我无法让它工作。

我的 XML 看起来像这样:

<ArrayOfProductFeedEntity>

    <ProductFeedEntity>
        <StockNo>123</StockNo>
        <MoreNodes>XXX</MoreNodes>
        <MoreNodes>XXX</MoreNodes>
    </ProductFeedEntity>

    <ProductFeedEntity>
        <StockNo>456</StockNo>
        <MoreNodes>XXX</MoreNodes>
        <MoreNodes>XXX</MoreNodes>
    </ProductFeedEntity>

    <ProductFeedEntity>
        <StockNo>456-A</StockNo>
        <MoreNodes>XXX</MoreNodes>
        <MoreNodes>XXX</MoreNodes>
    </ProductFeedEntity>

    <ProductFeedEntity>
        <StockNo>789</StockNo>
        <MoreNodes>XXX</MoreNodes>
        <MoreNodes>XXX</MoreNodes>
    </ProductFeedEntity>
</ArrayOfProductFeedEntity>

当我达到 456-A 时,我想备份到 456 并添加以下节点。我正在使用 foreach 循环遍历 $xml 变量。

$p = $xml->xpath("/ArrayOfProductFeedEntity/ProductFeedEntity[StockNo=$stock]");
$size = $p->addChild("Options")->addChild("Size");
$size->addChild("Name","Size");
$size->addChild("Value", $stock);

有什么想法吗?

您将始终需要一个循环,SimpleXMLElement::xpath() returns 一个 SimpleXMLElement 对象数组。即使表达式returns只有一个或none.

但是您所要求的可以直接在初始 XPath 表达式中完成。

你的表情:

/ArrayOfProductFeedEntity/ProductFeedEntity[StockNo='456-A']

您正在 ArrayOfProductFeedEntity 元素节点上执行该表达式,因此该表达式可以简化为:

ProductFeedEntity[StockNo='456-A']

现在从该节点开始,您可以获得其前面的兄弟节点:

ProductFeedEntity[StockNo='456-A']/preceding-sibling::*

并将其限制为第一个(最近的):

ProductFeedEntity[StockNo='456-A']/preceding-sibling::*[1]

完整示例:

$xml = new SimpleXMLElement($xml);
$expression = "ProductFeedEntity[StockNo='456-A']/preceding-sibling::*[1]";
foreach ($xml->xpath($expression) as $p) {
  $size = $p->addChild("Options")->addChild("Size");
  $size->addChild("Name","Size");
  $size->addChild("Value", $stock);
}
echo $xml->asXml();