English 中文(简体)
PHP SimpleXML XPath contains() to find other elements referenced by this element
原标题:

I m being given XML in the following format, and am parsing it with PHP s 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>

I m looping through the Units (Rooms) thus:

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

in an attempt to show the names off the Passengers (Pax) in each room.

But this xpath finds no-one, and the following gets everyone.

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

What s especially frustrating is that I ve successfully used XPath elsewhere in the same PHP for a very similar purpose, with no problems.

Any help/advice/suggestions will be much appreciated.


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)]
最佳回答

This:

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

is: Find any <Passenger> with a child <PaxNo> who s value contains the value of the child <PaxAssociated>. It would only work with such a data structure (which you clearly don t have):

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

So this is wrong on multiple accounts. What you mean is probably a dynamic XPath expression, like this:

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

This works on first glance, but it is not fail-safe, because "22" contains "2" as well. So doing a contains() alone won t get you anywhere. Correct would be:

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

This way you check "|22|" against "|2|", which would return false.

问题回答

暂无回答




相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签