PHP SimpleXML XPath contains()查找此元素引用的其他元素

PHP SimpleXML XPath contains()查找此元素引用的其他元素,php,xml,xpath,simplexml,contains,Php,Xml,Xpath,Simplexml,Contains,我得到了以下格式的XML,并使用PHP的SimpleXML解析它 <?xml version="1.0" encoding="UTF-8"?> <ManageMyBooking> <BookingInfo> <PartyDetails> <Passenger> <PaxNo>1</PaxNo> <

我得到了以下格式的XML,并使用PHP的SimpleXML解析它

<?xml version="1.0" encoding="UTF-8"?>
<ManageMyBooking>
    <BookingInfo>
        <PartyDetails>
            <Passenger>
                <PaxNo>1</PaxNo>
                <Title>Mrs</Title>
                <Surname>Murphy</Surname>
            </Passenger>
            <Passenger>
                <PaxNo>2</PaxNo>
                <Title>Mr</Title>
                <Surname>Murphy</Surname>
            </Passenger>
            <Passenger>
                <PaxNo>3</PaxNo>
                <Title>Miss</Title>
                <Surname>Murphy</Surname>
            </Passenger>
        </PartyDetails>
        <Accommodation>
            <Units>
                <Unit>
                    <UnitNo>1</UnitNo>
                    <UnitDesc>...</UnitDesc>
                    <PaxAssociated>1|2</PaxAssociated>
                </Unit>
                <Unit>
                    <UnitNo>2</UnitNo>
                    <UnitDesc>...</UnitDesc>
                    <PaxAssociated>3</PaxAssociated>
                </Unit>
            </Units>
        </Accommodation>
    </BookingInfo>
</ManageMyBooking>
特别令人沮丧的是,我在同一个PHP中的其他地方成功地将XPath用于非常类似的目的,没有任何问题

任何帮助/建议/建议都将不胜感激


编辑: 为完整起见,并回答多人提出的问题: 下面的代码在代码的其他地方也适用(尽管考虑到“22”与“2”之间可能存在的匹配,这不是100%正确)

//Flight[contains(PaxAssociated,./PaxNo)]
这:

is:查找具有子级
且其值包含子级
值的任何
。它仅适用于此类数据结构(您显然没有):

乍一看,这是可行的,但它不是故障安全的,因为“22”也包含“2”。因此,单独执行
contains()
将无法实现任何目标。正确的做法是:

$XPath = "//Passenger[contains('|". $Unit->PaxAssociated ."|', concat('|', PaxNo, '|'))]";

这样,您可以将“| 22 |”与“|2 |”进行核对,这将返回false。

我对元素上的xpath如何返回“//passenger”的任何结果感到困惑,因为在您的示例xml结构中,单元不包含乘客。您能介绍一下$accomodation对象是如何定义的吗?它似乎是SimpleXML对象的内置功能,单元元素是直接定义的创建了一个包含整个树的SimpleXML对象。有趣的功能-很高兴知道这一点,谢谢!@jezmck:不,不是这样。请参见下面的评论。-)最后一个代码片段中有一个小的输入错误,应该是
包含('.
(最后两个字符中的倒数)这里有同样的问题:“//passenger…”的xpath在$unit对象上运行时如何返回任何内容(除非$unit与标记中的“?$Unit被直接定义为包含整棵树的变量的子子子元素。@亨里克·欧宝:我怀疑你把
'//'
'/'
混淆了。前者总是从根节点开始,而不管上下文如何。后者考虑上下文。@亨里克·欧宝:它不包含整棵树,但仍然可以n参考它-毕竟它仍然是DOM的一部分。对于使用
/
的XPath查询,它不会影响您当前在DOM中的位置。
//Flight[contains(PaxAssociated,./PaxNo)]
//Passenger[contains(PaxNo,./PaxAssociated)]
<ManageMyBooking>
  <BookingInfo>
    <PartyDetails>
      <Passenger>
        <PaxNo>1|2</PaxNo>  <!-- note the exchanged value! -->
        <PaxAssociated>1</PaxAssociated>
      </Passenger>
    </PartyDetails>
  </BookingInfo>
</ManageMyBooking>
foreach ($Units->Unit as $Unit) {
  $XPath = "//Passenger[contains('". $Unit->PaxAssociated . "', PaxNo)]";
  foreach ($Unit->xpath($XPath) as $RoomPax) {
    // ...
  }
}
$XPath = "//Passenger[contains('|". $Unit->PaxAssociated ."|', concat('|', PaxNo, '|'))]";