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: 値に childの値が含ま<Passenger>れる子を検索します。そのようなデータ構造でのみ機能します(明らかに持っていません):<PaxNo><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 に答える