使用 DOMXPath 将 foreach 循环替换为 XPath 表达式
Replace a foreach loop with XPath expression using DOMXPath
我想使用 xpath 表达式替换 foreach 循环,但我需要一个 DOMXPath 对象 return 多个列表。
我有以下 XML(简化),我使用 DOMDocument and DOMXPath 对其进行迭代:
<a:RoomsType>
<a:Rooms>
<a:Room>
<a:RPH>0</a:RPH>
</a:Room>
<a:Room>
<a:RPH>1</a:RPH>
</a:Room>
<a:Room>
<a:RPH>2</a:RPH>
</a:Room>
<a:Room>
<a:RPH>0</a:RPH>
</a:Room>
<a:Rooms>
<a:RoomsType>
我想按 RPH 编号拆分房间,为每个 RPH 编号创建一个房间列表。目前,我正在使用以下代码:
//$xpath is a DOMXPath object
$roomsToIterate = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room");
$roomList = array();
foreach ($roomsToIterate as $room) {
$rphCandidate = $room->getElementsByTagName("RPH")->item(0)->nodeValue;
if (!isset($roomList[$rphCandidate])) {
$roomList[$rphCandidate] = array();
}
$roomList[$rphCandidate][] = $room;
}
这目前有效,但我想用 Xpath 表达式替换 foreach 循环。我可以使用表达式 $rooms = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room[a:RPH='{$rph}']");
,其中 $rph
是一个数字,但如果我不知道 RPH(它可以是 0 到 99 之间的任何值),我该怎么办呢?可能吗?
简而言之,有什么方法可以使用 XPath 替换我的 foreach 循环吗?
我在考虑使用 registerPhpFunctions 和自定义函数,但我担心这种方法与 foreach 循环相比的性能
Xpath 1.0 表达式将 return 一个节点列表,如果您使用像 descendant
或 ancestor
这样的轴,它们可以在某种程度上展平现有结构,但它将是节点列表。它不能对它们进行分组或聚合。
您可以获取具有特定 RPH
值的节点列表。但是您需要为每个值执行此操作,结果将是另一个循环。这意味着获取所有 RPH
值,使它们唯一,迭代它们并为每个值执行 Xpath 表达式。
您当前的解决方案很好。
我想使用 xpath 表达式替换 foreach 循环,但我需要一个 DOMXPath 对象 return 多个列表。
我有以下 XML(简化),我使用 DOMDocument and DOMXPath 对其进行迭代:
<a:RoomsType>
<a:Rooms>
<a:Room>
<a:RPH>0</a:RPH>
</a:Room>
<a:Room>
<a:RPH>1</a:RPH>
</a:Room>
<a:Room>
<a:RPH>2</a:RPH>
</a:Room>
<a:Room>
<a:RPH>0</a:RPH>
</a:Room>
<a:Rooms>
<a:RoomsType>
我想按 RPH 编号拆分房间,为每个 RPH 编号创建一个房间列表。目前,我正在使用以下代码:
//$xpath is a DOMXPath object
$roomsToIterate = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room");
$roomList = array();
foreach ($roomsToIterate as $room) {
$rphCandidate = $room->getElementsByTagName("RPH")->item(0)->nodeValue;
if (!isset($roomList[$rphCandidate])) {
$roomList[$rphCandidate] = array();
}
$roomList[$rphCandidate][] = $room;
}
这目前有效,但我想用 Xpath 表达式替换 foreach 循环。我可以使用表达式 $rooms = $this->xpath->query("//a:RoomsType/a:Rooms/a:Room[a:RPH='{$rph}']");
,其中 $rph
是一个数字,但如果我不知道 RPH(它可以是 0 到 99 之间的任何值),我该怎么办呢?可能吗?
简而言之,有什么方法可以使用 XPath 替换我的 foreach 循环吗?
我在考虑使用 registerPhpFunctions 和自定义函数,但我担心这种方法与 foreach 循环相比的性能
Xpath 1.0 表达式将 return 一个节点列表,如果您使用像 descendant
或 ancestor
这样的轴,它们可以在某种程度上展平现有结构,但它将是节点列表。它不能对它们进行分组或聚合。
您可以获取具有特定 RPH
值的节点列表。但是您需要为每个值执行此操作,结果将是另一个循环。这意味着获取所有 RPH
值,使它们唯一,迭代它们并为每个值执行 Xpath 表达式。
您当前的解决方案很好。