PHP SimpleXML XPath bu öğe tarafından başvurulan diğer öğeleri bulmak için () içerir

1 Cevap php

Ben aşağıdaki biçimde XML verilmektedir ediyorum ve PHP'nin SimpleXML ile ayrıştırma duyuyorum.

<?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>

Ben böylece Birimleri (Odalar) döngü ediyorum:

// $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 />
<?  		}
    	}
    } ?>

Her odada Yolcu (Pax) kapalı adlarını göstermek için bir girişim.

But bu xpath hiç birini bulur ve aşağıdaki herkes alır.

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

Ne özellikle sinir bozucu başarıyla herhangi bir sorun ile, çok benzer bir amaç için başka bir yerde aynı PHP XPath'i kullanmış olmasıdır.

Herhangi bir yardım / tavsiye / öneri çok takdir edilecektir.


Edit: for completeness, and to answer a question from multiple people: The following works elsewhere in the code, (though not 100% correctly given the possible matching on '22' vs '2'.

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

1 Cevap

Bu:

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

olduğunu: <PaxNo> kim değeri <PaxAssociated> çocuğun değerini içerir bulunuyor herhangi bir <Passenger> bir çocuk bulun. Sadece (açıkça yok) böyle bir veri yapısı ile çalışmak:

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

Yani bu birden fazla hesap yanlış. Eğer mean bu gibi muhtemelen dinamik bir XPath ifadesi nedir:

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

Bu ilk bakışta üzerinde çalışır, ancak "22" de "2" içeriyor çünkü, fail-safe değildir. Bunu yaparken bir contains() yalnız sizi almazsınız anywhere. Doğru olacaktır:

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

"| 2 |" return false hangi karşı "| | 22" kontrol bu şekilde.