• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 184
  • Last Modified:

Extracting data from particular attribute using simplexml

Hi,

I have the following xml feed:
<tour>
<tourName>Amazon Riverboat Adventure</tourName>
<dossierCode>PVIIA</dossierCode>
<tripDetails>
<tripDetail type="StartFinish">ex Lima</tripDetail>
<tripDetail type="What's Included">Lots of stuff </tripDetail>
<tripDetail type="Whats not included">Not much </tripDetail>
</tripDetails>

Open in new window


I need a way to be able to save each of the tripDetails as a seperate value. The "types" are always constant and i have a list of them.

I therefore want to be able to say $startfinish = 'ex Lima', $whatsincluded = 'Lots of stuff' etc.

The code i have so far is:

<?php
if(!$xml=simplexml_load_file('xmlfeed.xml')){
    trigger_error('Error reading XML file',E_USER_ERROR);
}
foreach ($xml->tourName as $tourname)
foreach ($xml->dossierCode as $agentcode)
?> 

Open in new window


which obviously get's me the first two instances of the XML. When i move onto the tripDetail section though, i tried to use:

foreach ($xml->tripDetails->tripDetail[0] as $startfinish)

Open in new window


this didn't produce anything. If i remove the [0], it just displays the last result in the array.

Any help - greatly appreciated!

Many thanks!
0
gnrmatt
Asked:
gnrmatt
  • 8
  • 7
1 Solution
 
Ray PaseurCommented:
The XML above is not valid because of the apostrophe in the text.  You need to entitize those things, I think.  Something like &apos;
0
 
gnrmattAuthor Commented:
Hi Ray,

Sorry - what apostrophe are you refering to. The XML feed is direct from a very large agency so I don't think there is anything wrong with their XML feed out?

Thanks!

Matt
0
 
Ray PaseurCommented:
See if this helps.  http://www.laprbass.com/RAY_temp_gnrmatt.php
Outputs:
StartFinish => ex Lima
What's Included => Lots of stuff
Whats not included => Not much
<?php // RAY_temp_gnrmatt.php
error_reporting(E_ALL);
echo "<pre>";

// TEST DATA WITH MINOR MODIFICATIONS
$xml = <<<XML
<tour>
<tourName>Amazon Riverboat Adventure</tourName>
<dossierCode>PVIIA</dossierCode>
<tripDetails>
<tripDetail type="StartFinish">ex Lima</tripDetail>
<tripDetail type="What&apos;s Included">Lots of stuff </tripDetail>
<tripDetail type="Whats not included">Not much </tripDetail>
</tripDetails>
</tour>
XML;

// MAKE AN OBJECT (SEE http://php.net/manual/en/simplexml.examples-basic.php)
$obj = SimpleXML_Load_String($xml);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// USE AN ITERATOR TO GET INFORMATION OUT OF THE OBJECT
foreach ($obj->tripDetails->tripDetail as $t)
{
    $a = (string)$t["type"];
    $d = (string)$t;
    echo PHP_EOL . "$a => $t";
}

Open in new window

0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
Ray PaseurCommented:
Hey, Matt - check line 6 in the type= attribute.  It may not matter in the attributes, only in the text.  Not sure about that.  But this reference might help explain better.
http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references

Best regards, ~Ray
0
 
gnrmattAuthor Commented:
Okay thats great - but then i need to be able to save those as variables set by me.

I.e.
$startfinish = 'ex Lima'
$whatsincluded = 'Lots of stuff'
etc

Is there a way i can do this?
0
 
gnrmattAuthor Commented:
Is there some way i can use the below?
foreach ($xml->tripDetails->tripDetail as $startfinish)

Open in new window


This produces the last result. Surely there is a way of making it produce the first result?
0
 
Ray PaseurCommented:
To save the variables where exactly?

These two code snippets look a lot alike to me!
foreach ($xml->tripDetails->tripDetail as $startfinish)

Open in new window

and line 25 of the script I posted.
foreach ($obj->tripDetails->tripDetail as $t)

Open in new window

0
 
gnrmattAuthor Commented:
I need the variables set as
$startfinish = 'ex Lima'
$whatsincluded = 'Lots of stuff'
$whatsnotincluded = 'Not much'

So that i can call on them later in any specifc order I want. I.e. I could say:

Whats Not Included? <?php echo $whatsnotincluded; ?>
Tour Starts and Finishs <?php echo $startfinish; ?>
What is included? <?php echo $whatsincluded; ?>

I don't want to have any paricular order to which i have to use the variables and I want to be able to use them freely as my own variables.

As said, the below will bring up just the final result. I.e. in the original example, it only brings up 'Not Much' and that get's saved as the vairable $startfinish.

I hope i'm making sense. :-)
0
 
Ray PaseurCommented:
Yeah, that makes sense.  Let me experiment with it a little bit.  It may not be exactly what you have there but it can follow a workable design pattern.
0
 
Ray PaseurCommented:
http://www.laprbass.com/RAY_temp_gnrmatt.php
Outputs:
array(3) {
  ["StartFinish"]=>
  string(7) "ex Lima"
  ["WhatsIncluded"]=>
  string(14) "Lots of stuff "
  ["Whatsnotincluded"]=>
  string(9) "Not much "
}

ex Lima
<?php // RAY_temp_gnrmatt.php
error_reporting(E_ALL);
echo "<pre>";

// TEST DATA WITH MINOR MODIFICATIONS
$xml = <<<XML
<tour>
<tourName>Amazon Riverboat Adventure</tourName>
<dossierCode>PVIIA</dossierCode>
<tripDetails>
<tripDetail type="StartFinish">ex Lima</tripDetail>
<tripDetail type="What&apos;s Included">Lots of stuff </tripDetail>
<tripDetail type="Whats not included">Not much </tripDetail>
</tripDetails>
</tour>
XML;

// MAKE AN OBJECT (SEE http://php.net/manual/en/simplexml.examples-basic.php)
$obj = SimpleXML_Load_String($xml);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// USE AN ITERATOR TO GET INFORMATION OUT OF THE OBJECT
$arr = array();
foreach ($obj->tripDetails->tripDetail as $t)
{
    // GET THE TYPE ATTRIBUTE NAME
    $a = (string)$t["type"];

    // MAKE A USEFUL VARIABLE NAME
    $a = html_entity_decode($a);
    $a = preg_replace('/[^A-Z]/i', NULL, $a);

    // GET THE VALUE FROM THE tripDetail TAG
    $d = (string)$t;

    // SAVE THE VARIABLE NAME AND THE VALUE IN AN ASSOCIATIVE ARRAY
    $arr[$a] = $d;
}

// SHOW THE ARRAY
var_dump($arr);

// INJECT THE VARIABLES INTO THE LOCAL NAMESPACE
extract($arr);

// SHOW WHAT ONE OF THEM CONTAINS
echo PHP_EOL . $StartFinish;

Open in new window

0
 
gnrmattAuthor Commented:
Hi Ray,

This looks amazing - the only slight difficulty i'm not having is getting it to connect to my external xmlfeed. I'm sure it's just how i'm trying to load it?

I have:
<?php
$getagentcode = $_GET['acode'];
?>
<?php
$xml = simplexml_load_file('http://username:password@www.site.com/tours/' . $getagentcode . '/');
// MAKE AN OBJECT (SEE http://php.net/manual/en/simplexml.examples-basic.php)
$obj = SimpleXML_Load_String($xml);

// ACTIVATE THIS TO SEE THE OBJECT
// var_dump($obj);

// USE AN ITERATOR TO GET INFORMATION OUT OF THE OBJECT
$arr = array();
foreach ($obj->tripDetails->tripDetail as $t)
{
    // GET THE TYPE ATTRIBUTE NAME
    $a = (string)$t["type"];

    // MAKE A USEFUL VARIABLE NAME
    $a = html_entity_decode($a);
    $a = preg_replace('/[^A-Z]/i', NULL, $a);

    // GET THE VALUE FROM THE tripDetail TAG
    $d = (string)$t;

    // SAVE THE VARIABLE NAME AND THE VALUE IN AN ASSOCIATIVE ARRAY
    $arr[$a] = $d;
}

// SHOW THE ARRAY
var_dump($arr);

// INJECT THE VARIABLES INTO THE LOCAL NAMESPACE
extract($arr);

// SHOW WHAT ONE OF THEM CONTAINS
echo PHP_EOL . $StartFinish;
?>
Tour Name: <?php echo $tourname; ?> <br>
Agent Code: <?php echo $agentcode; ?> <br>
Description: <?php echo $description; ?><br>
Start/Finish: <?php echo $startfinish; ?><br>
Test2: <?php echo $tripdetail; ?>

Open in new window

0
 
gnrmattAuthor Commented:
I should have said, the error that appears is:

Warning: Invalid argument supplied for foreach() in /home/bookedy/public_html/xmltest.php on line 14

Open in new window


which i'm presuming means it's not connecting to the feed correctly?
0
 
Ray PaseurCommented:
Look at line 9 and line 10.  Remove the comment from line 10 and see what is in the object.  You might want to print the URL you are accessing.  You might want to use error_reporting(E_ALL) like I did in my example.
0
 
gnrmattAuthor Commented:
Excellent - Thanks Ray for all your work and help on this. Work's perfectly for me now!
0
 
Ray PaseurCommented:
Thanks for the points -- great question! ~Ray
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now