1

我得到了以下格式的 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>

我正在遍历单元(房间),因此:

// $Accommodation is a SimpleXML Object defined earlier, and able to provide relevant info
<?  foreach ($Accommodation->Units as $Units) {
        foreach ($Units->Unit as $Unit) {
        // (room/unit details echoed out here)
            foreach ($Unit->xpath('//Passenger[contains(PaxAssociated,./PaxNo)]') as $RoomPax) { ?>
<?= $RoomPax->Title $RoomPax->Surname" ?><br />
<?= "$RoomPax->Title $RoomPax->Surname" ?><br />
<?          }
        }
    } ?>

试图在每个房间里显示乘客(Pax)的名字。

但是这个 xpath 没有找到任何人,以下得到了所有人。

//Passenger[contains(PaxNo,./PaxAssociated)]

尤其令人沮丧的是,我已经成功地在同一个 PHP 中的其他地方使用了 XPath,用于非常相似的目的,没有任何问题。

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


编辑:为了完整性,并回答多人提出的问题:以下代码在代码的其他地方有效(尽管考虑到“22”与“2”的可能匹配,但不是 100% 正确。

//Flight[contains(PaxAssociated,./PaxNo)]
4

1 回答 1

3

这:

//Passenger[contains(PaxNo,./PaxAssociated)]

is: 查找任何<Passenger>具有 child<PaxNo>的 value 包含child 的 value <PaxAssociated>。它只适用于这样的数据结构(你显然没有):

<ManageMyBooking>
  <BookingInfo>
    <PartyDetails>
      <Passenger>
        <PaxNo>1|2</PaxNo>  <!-- note the exchanged value! -->
        <PaxAssociated>1</PaxAssociated>
      </Passenger>
    </PartyDetails>
  </BookingInfo>
</ManageMyBooking>

所以这在多个帐户上是错误的。您的意思可能是动态 XPath 表达式,如下所示:

foreach ($Units->Unit as $Unit) {
  $XPath = "//Passenger[contains('". $Unit->PaxAssociated . "', PaxNo)]";
  foreach ($Unit->xpath($XPath) as $RoomPax) {
    // ...
  }
}

乍一看这是可行的,但它不是故障安全的,因为“22”也包含“2”。所以contains()单独做一个不会让你到任何地方。正确的是:

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

这样你检查“|22|” 反对“|2|”,这将返回 false。

于 2009-11-13T13:03:45.837 回答