xpath search for a php variable - php

I am trying to search for a php variable in an xml file using xpath, but failing miserably. It works with a hard coded value, so I am nearly there..
<visitors>
<detail>
<id>876867</id>
<name>Bob McHaggis</name>
<email>bob#gmail.com</email>
</detail>
<detail>
<id>897987</id>
<name>Mark McBob</name>
<email>mark#gmail.com</email>
</detail>
</visitors>
<?php $sxe = simplexml_load_file("/CaptivePortal/visitors.xml");
foreach($sxe->xpath('//visitors/detail') as $item){
$row = simplexml_load_string($item->asXML());
$v = $row->xpath('//id[. ="'.$_COOKIE["judsons"].'"]');
} echo $v[0]; ?>
This works great checks for an id against the id stored in the cookie. But based on that value being found how do I access the name and email for the key matched?
Found & matched: 897987
I want to echo the name and email to, so based on that is Mark McBob & mark#gmail.com

My initial advice would be to take a good few minutes to (re-)read through the SimpleXML Basic Usage page in the PHP manual.
For selecting a single item within the XML file, there is no need at all to loop over anything. The example code below, and why it is different from yours, should become clear after familiarising yourself with the page mentioned above.
<?php
$search_id = (int) $_COOKIE["judsons"];
$visitors = simplexml_load_file("/CaptivePortal/visitors.xml");
$details = $visitors->xpath("detail[id='$search_id']");
if (empty($details)) {
echo "No details found for '$search_id'.";
} else {
$detail = $details[0];
$name = (string) $detail->name;
$email = (string) $detail->email;
echo "$name's email is $email";
}
The idea above is that $details will be an array containing hopefully just one <detail> element. It could be an empty array if no <detail> was found with the specified <id>, which is what the if(empty(…)) checks for. If the $details array is not empty, we're really only interested in the first one ($details[0]).
To access the information available within the <detail>, as explained on the "basic usage" page, the elements can be accessed with normal object property syntax ($detail->name). Doing so returns an object for that item (e.g. the <name>), so to get at the value as a string the object is type cast using (string).

You're actually doing quite a bit you don't need to there. For one thing, you don't need the loop. For another, inside your loop, you convert the context XML into a string (::asXML()), then convert it back into XML (simplexml_load_string()).
All you need is:
$xml = "<visitors><detail><id>876867</id><name>Bob McHaggis</name><email>bob#gmail.com</email></detail><detail><id>897987</id><name>Mark McBob</name><email>mark#gmail.com</email></detail></visitors>";
$sxe = simplexml_load_string($xml);
$row = $sxe->xpath('detail[id = '.$_COOKIE["judsons"].']');
That gets you the row. To extract part of it:
$name = $row[0]->xpath('name');
echo $name[0]; //Mark McBob

Related

Using SimpleXML to extract data from XML page returning empty array

I'm trying to extract the values of all elements named wardtitle from this xml page:
https://democracy.ashfield-dc.gov.uk/mgWebService.asmx/GetCouncillorsByWard
Here's the code I'm currently trying:
$xml = simplexml_load_file("https://democracy.ashfield-dc.gov.uk/mgWebService.asmx/GetCouncillorsByWard");
var_dump($xml->children());
$ward = (string) $xml->wardtitle;
echo $ward;
print_r($xml->xpath("//email"));
The children dump seems to work fine, the $ward variable returns nothing, then the xpath attempt returns the correct number of results, but all empty...
Any help very much appreciated.
According to xml structure: wardtitle is a node of each ward, which in turn - node of wards, so, to echo wardtitle of first ward:
echo $xml->wards->ward[0]->wardtitle;
As for emails - everything works fine:
foreach ($xml->xpath("//email") as $email) {
echo $email;
}

XML tagname is a PHP function

I'm trying to parse an XML file in PHP with the simplexml_load_file function. Everything is fine, except my XML file has a <TIME> tag, which is a PHP function.
So the following code fails to get the tag value :
$xml = simplexml_load_file('some_xml_file.xml');
$value = $xml->SOME_TAG->TIME;
How do I get this value?
From the PHP manual:
Accessing elements within an XML document that contain characters not
permitted under PHP's naming convention (e.g. the hyphen) can be
accomplished by encapsulating the element name within braces and the
apostrophe.
Example #3 Getting
<?php
include 'example.php';
$xml = new SimpleXMLElement($xmlstr);
echo $xml->movie->{'great-lines'}->line; // "PHP solves all my web problems"
?>
And if you need to get an attribute you can do this:
So far, we have only covered the work of reading element names and
their values. SimpleXML can also access element attributes. Access
attributes of an element just as you would elements of an array.
foreach ($xml->movie[0]->rating as $rating) {
switch((string) $rating['type'])
This works for me
<?php
$xmlString = "<top><middle><TIME>1:27</TIME></middle></top>";
$xml = simplexml_load_string($xmlString);
echo $xml->middle->TIME;
php /tmp/xml.php
1:27
Check the contents of your XML file. For your PHP code to work, it should AT LEAST contain this:
<XML>
<SOME_TAG>
<TIME>1:27</TIME>
</SOME_TAG>
</XML>
When I use this XML file combined with your code, it works as expected.
Thanks everyone, I manage to get the value but there's still something strange.
XML example :
<INGREDIENTS>
<INGREDIENT>
<NAME>Potatoes</NAME>
<AMOUNT>10 kg</AMOUNT>
<TME>20 min</TIME>
</INGREDIENT>
</INGREDIENTS>
PHP code to get NAME, AMOUNT and TIME values :
$ing = $xml->INGREDIENTS->INGREDIENT;
$name = $ing->NAME;
$amount= $ing->AMOUNT;
$time= $ing->TIME;
echo $name." / ".$amount." / ".$time;
Result :
Potatoes / 10 kg /
However, if I use the whole path to the TIME tag :
$ing = $xml->INGREDIENTS->INGREDIENT;
$name = $ing->NAME;
$amount= $ing->AMOUNT;
$time= $xml->INGREDIENTS->INGREDIENT->TIME;
echo $name." / ".$amount." / ".$time;
Result :
Potatoes / 10 kg / 20 min
Can anyone explain why it's working this way ?

how to display SimpleXMLElement with php

Hi I have never used xml but need to now, so I am trying to quickly learn but struggling with the structure I think. This is just to display the weather at the top of someones website.
I want to display Melbourne weather using this xml link ftp://ftp2.bom.gov.au/anon/gen/fwo/IDV10753.xml
Basically I am trying get Melbourne forecast for 3 days (what ever just something that works) there is a forecast-period array [0] to [6]
I used this print_r to view the structure:
$url = "linkhere";
$xml = simplexml_load_file($url);
echo "<pre>";
print_r($xml);
and tried this just to get something:
$url = "linkhere";
$xml = simplexml_load_file($url);
$data = (string) $xml->forecast->area[52]->description;
echo $data;
Which gave me nothing (expected 'Melbourne'), obviously I need to learn and I am but if someone could help that would be great.
Because description is an attribute of <area>, you need to use
$data = (string) $xml->forecast->area[52]['description'];
I also wouldn't rely on Melbourne being the 52nd area node (though this is really up to the data maintainers). I'd go by its aac attribute as this appears to be unique, eg
$search = $xml->xpath('forecast/area[#aac="VIC_PT042"]');
if (count($search)) {
$melbourne = $search[0];
echo $melbourne['description'];
}
This is a working example for you:
<?php
$forecastdata = simplexml_load_file('ftp://ftp2.bom.gov.au/anon/gen/fwo/IDV10753.xml','SimpleXMLElement',LIBXML_NOCDATA);
foreach($forecastdata->forecast->area as $singleregion) {
$area = $singleregion['description'];
$weather = $singleregion->{'forecast-period'}->text;
echo $area.': '.$weather.'<hr />';
}
?>
You can edit the aforementioned example to extract the tags and attributes you want.
Always remember that a good practice to understand the structure of your XML object is printing out its content using, for instance, print_r
In the specific case of the XML you proposed, cities are specified through attributes (description). For this reason you have to read also those attributes using ['attribute name'] (see here for more information).
Notice also that the tag {'forecast-period'} is wrapped in curly brackets cause it contains a hyphen, and otherwise it wouldn generate an error.

Error reading from webservices xml file

I'm trying to get a product list for a client from a webservices xml file over to an SQL databse using a little php script, but I can't seem to get it to work.
The relevant code is as follows:
$c = 0;
...
$xml = simplexml_load_file($completeurl);
$listingsArray = $xml->listings->listing;
foreach($listingsArray as $listing){
$addition[0] = $listing[$c]->type;
$addition[1] = $listing[$c]->condition;
//etcetera
c = c + 1;
}
The XML file is formated like:
<inventory>
<listings>
<listing>
//tags for type, condition, etc
</listing>
</listings>
</inventory>
$completeurl is a string that contains the url of the xml file
$addition is an array that's defined earlier in the code
I've been working on this for a while now, but I can't seem to figure out where the error is in my code. The problem that I'm having is that $listingsArray should have close to 100 elements in it, but is constantly coming up with 0. Anybody see what I'm doing wrong?
EDIT: I tried changing
$listingsArray = $xml->listings->listing;
to
$listingsArray = $xml->listings;
But empty strings are still being written to the $addition array. A var_dump of listingsArray show that all of the information is in there, though.
If you want each listing i believe you are going a child too deep.
$listingsArray = $xml->listings->listing;
shoudl be
$listingsArray = $xml->listings;
foreach($listingsArray as $listing){
$addition[0] = $listing[$c]->type;
$addition[1] = $listing[$c]->condition;
//etcetera
}
additionally what is $c? It also helps to post your exact errors. When debugging inserting var_dumps is extremely helpful. If you think the probelm is $listingArray
print it out and see if it contains the data you want.
changing
$listingsArray = $xml->listings->listing;
to
$listingsArray = $xml->listings;
Should solve the issue. You set $listingsArray to the array of listings, then the foreach tries to go down another level

PHP Parse XML with Attributes

I have an XML document that I am trying to get some of the values for and don't know how to get to the attributes. An example of the structure and values are below:
<vin_number value="3N1AB51D84L729887">
<common_data>
<engines>
</engines>
</common_data>
<available_vehicle_styles>
<vehicle_style name="SE-R 4dr Sedan" style_id="100285116" complete="Y">
<engines>
<engine brand="" name="ED 2L NA I 4 double overhead cam (DOHC) 16V"></engine>
</engines>
</vehicle_style>
</available_vehicle_styles>
</vin_number>
I am trying to get the engine["name"] attribute (NOT "ENGINES"). I thought the following would work but I get errors (I cant parse past "vehicle_style")
$xml = simplexml_load_file($fileVIN);
foreach($xml->vin_number->available_vehicle_styles->vehicle_style->engines->engine->attributes() as $a => $b) {
echo $b;
}
Assuming your XML is structured in the same was as this example XML, the following two snippets will get the engine name.
The property hierarchy way (split onto multiple lines so you can read it).
$name = (string) $xml->vin_number
->available_vehicle_styles
->vehicle_style
->engines
->engine['name'];
Or the more concise XPath way.
$engines = $xml->xpath('//engines/engine');
$name = (string) $engines[0]['name'];
Unless there are multiple engine names in your XML, there is no need to use a foreach loop at all.
(See both snippets running on a codepad.)
Use the SimpleXMLElement::attributes method to get the attributes:
foreach($xml->available_vehicle_styles->vehicle_style as $b) {
$attrs = $b->attributes();
echo "Name = $attrs->name";
}
Note: I slightly changed the "path" to the element starting from $xml because that's how it loaded the fragment for me.
By this layout, there could be more than one engine per engines block, so you have to explicitly pick the first one. (Assuming you know for sure there's only going to be one.)
$name = $xml->available_vehicle_styles->vehicle_style->engines->engine[0]->attributes()->name;

Categories