我在这里用头撞墙。我正在尝试遍历一个 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() 返回一个 SimpleXMLElement 对象的数组。即使表达式只返回一个或无。
但是您要求的内容可以直接在初始 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();