PHP SimpleXML XPath contains()查找此元素引用的其他元素
我得到了以下格式的XML,并使用PHP的SimpleXML解析它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 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, '|'))]";