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();
我在这里用头撞墙。我正在尝试遍历 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();