简体   繁体   中英

Read XML attributes using PHP

I m using a API to display results wrt to search query.

The output will be in the form of XML, I need to parse the XML and display the result in the browser.

The file contains many attributes from which im not sure how to extract the results.

Here is my code:

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns3:tourDetailsFullResponse xmlns:ns2="http://example.com/" xmlns:ns3="http://example.com/" xmlns:ns4="http://www.example.com/">

<ns4:MarketLocalisedTourData SellingCompanyCode="CODE1" OperatingProductCode="CODE2" MarketVariationCode="CODE3" Duration="8" Currency="USD" CatalogueCode="CODE4" TropicsBrochureCode="CODE5" BrandCode="CODE6" BookableOnline="true">

<ns4:TourInfo>
<ns4:TourName>London to Rome Highlights 2013</ns4:TourName>
<ns4:Metadata>
    <ns4:TourCategories>
        <ns4:TourCategory Name="TourStyles">
            <ns4:CategoryValue Name="European Discoveries"/>
        </ns4:TourCategory>
    </ns4:TourCategories>
    <ns4:Brochures>
        <ns4:Brochure Name="CostSaver 2013" Code="CODE1"/>
    </ns4:Brochures>
</ns4:Metadata>
<ns4:ContinentsVisited>
    <ns4:Continent Name="Europe" Code="EURO"/>
</ns4:ContinentsVisited>
<ns4:CountriesVisited>
    <ns4:Country Name="France" Continent="EURO" Code="FR"/>
    <ns4:Country Name="United Kingdom" Continent="EURO" Code="GB"/>
    <ns4:Country Name="Italy" Continent="EURO" Code="IT"/>
    <ns4:Country Name="Switzerland" Continent="EURO" Code="CH"/>
</ns4:CountriesVisited>
<ns4:LocationsVisited>
    <ns4:Location Name="Paris" Country="FR"/>
    <ns4:Location Name="Dover" Country="GB"/>
    <ns4:Location Name="London" Country="GB"/>
    <ns4:Location Name="Rome" Country="IT"/>
    <ns4:Location Name="Calais" Country="FR"/>
    <ns4:Location Name="Venice" Country="IT"/>
    <ns4:Location Name="Lucerne" Country="CH"/>
    <ns4:Location Name="Florence" Country="IT"/>
</ns4:LocationsVisited>
<ns4:Description>A lively journey through elegant Paris, gorgeous Lake Lucerne, charming Venice and cultural Florence, bookended by stays in London and legendary Rome. Spend a day at leisure in London and get the best views of Rome from high up in St. Peter’s Basilica before throwing a lucky coin in Trevi Fountain.</ns4:Description>
<ns4:Assets>
    <ns4:Image Width="297" Url="http://www.example.com/imageurl" Type="map" Name="route_map" Height="297" Caption="route_map"/>
    <ns4:Image Width="600" Url="http://www.example.com/imageurl" Type="map" Name="route_map" Height="600" Caption="route_map"/>
    <ns4:Image Width="531" Url="http://www.example.com/imageurl" Type="photo" Name="primary_image" Height="531" Caption="primary_image"/>
    <ns4:Image Width="125" Url="http://www.example.com/imageurl" Type="photo" Name="primary_image" Height="125" Caption="primary_image"/>
</ns4:Assets>
  ....continues

Now i want to extract the continents visited , countries visited, locations visited, itinerary, assests etc...

I tried using simple xml like the following

$feed = "response1_full.xml";

$xml = simplexml_load_file($feed);

print_r($xml);

foreach($xml->LocationsVisited[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}
also tried 
foreach($xml->TourInfo->LocationsVisited[0]->attributes() as $a => $b) {
    echo $a,'="',$b,"\"\n";
}

also tried all other possibilities which results in same error

Fatal error: Call to a member function attributes() on a non-object in C:\\xampp\\htdocs\\test\\xmlread2.php on line 10

I m searching a solution for this more than couple of days.

If you want to traverse into children in their own namespace you have to tell SimpleXMLElement which namespace:

$ns4 = $xml->children('S', true)->Body
        ->children('ns3', true)->tourDetailsFullResponse
            ->children('ns4', true);

$locations = $ns4->MarketLocalisedTourData->TourInfo->LocationsVisited->Location;

foreach ($locations as $location) {
    $attributes = $location->attributes();
    echo $attributes['Name'];
    echo $attributes['Country'];
}

However you can make your life more easy by using xpath with the namespace(s) you're interested in by registering them .

what does $xml have? can you print the result. And if it does not contain the any thing

then the problem is with namespace look at he following question: Remove namespace from XML using PHP

$feed = "response1_full.xml";
echo "<pre>";
$sxe = simplexml_load_file($feed);
if ($sxe === false) {
echo "Failed loading XML\n";
foreach(libxml_get_errors() as $error) {
    echo "\t", $error->message;
}
}
if (file_exists('response1_full.xml')) {
$xml = simplexml_load_file('response1_full.xml');
 //print_r($xml);
 } else {
exit('Failed to open test.xml.');
}
print_r($sxe->Body->tourDetailsFullResponse->MarketLocalisedTourData->TourInfo->LocationsVisited->Location[0]);
print_r($sxe->Body->tourDetailsFullResponse->MarketLocalisedTourData->TourInfo->LocationsVisited->Location[1]);

Finally i managed to find the answer through DOM.

@Deepak Srinivasan : I tried your suggestions to register the namespace before executing but i didnt get over it, may bim not sure how to proceed.

@m4t1t0: Thank you for your response.

i have pasted the pastebin url of the full file, You all can see the file from the URL specified below the answer.

I got the solution using the getAttribute method

$doc = new DOMDocument();
$doc->load( 'response1_full.xml' );

//tourname
$tname = $doc->getElementsByTagName( "TourName" );
$tourname = $tname->item(0)->nodeValue;
echo $tourname;
//locations visited
$locations = $doc->getElementsByTagName( "Location" );
foreach( $locations as $location )
{

    $locationname = $location->getAttribute('Name');
    $locationcountry = $location->getAttribute('Country');

    echo $locationname.'-'.$locationcountry.'<br>';
}

Which prints out the required details exactly.

But now i have a small doubt in the same file, I have some information's in nested format, is there anyway that i can pull it easily.!?

Here is my file for that http://pastebin.com/iWQf6j4K

Insde the file you can see a section

<ns4:WhatsIncluded>

which has title and text(ul - li format)

Is there any way i can pull the datas inside this secion. if i pull data from Text under Section i get the li items totally as a single paragraph,

but when i use foreach inside Text i get only the first li item,

I also tried foreach for Text ul , but still only one result.

Any suggestions..

Many thanks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM