【问题标题】:Replace a foreach loop with XPath expression using DOMXPath使用 DOMXPath 将 foreach 循环替换为 XPath 表达式
【发布时间】:2017-01-16 17:09:07
【问题描述】:

我想用一个 xpath 表达式替换一个 foreach 循环,但我需要一个 DOMXPath 对象来返回多个列表。

我有以下 XML(简化),我使用 DOMDocumentDOMXPath 对其进行迭代:

<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-&gt;xpath-&gt;query("//a:RoomsType/a:Rooms/a:Room[a:RPH='{$rph}']");$rph 是一个数字,但是如果我不知道RPH(它可以是0 到99 之间的任何值),我该怎么做。有可能吗?

简而言之,有没有办法使用 XPath 替换我的 foreach 循环?

我在考虑使用registerPhpFunctions 和自定义函数,但我担心这种方法与foreach 循环相比的性能

【问题讨论】:

  • 不,您仍然需要foeach。您必须迭代房间以创建嵌套结果或可能的 $rph 值以获取组。
  • 感谢您的评论。所以,我原来的方法是正确的。对于任何新的改进想法,我将保持这个问题的开放,但如果你愿意,你可以发表你的评论作为答案。如果我没有收到任何新建议,我会将其标记为正确。

标签: php xml xpath foreach domxpath


【解决方案1】:

Xpath 1.0 表达式将返回一个节点列表,如果您使用像 descendantancestor 这样的轴,它们可以在某种程度上展平现有结构,但它将是一个节点列表。它不能对它们进行分组或聚合。

您可以获取具有特定 RPH 值的节点列表。但是对于每个值,您都需要这样做,结果将是另一个循环。这意味着获取所有 RPH 值,使其唯一,迭代它们并为每个值执行 Xpath 表达式。

您当前的解决方案很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2015-01-26
    • 1970-01-01
    • 2019-04-04
    • 2018-08-20
    • 2017-04-26
    相关资源
    最近更新 更多