Separating values from XML using php with xpath - php

I need help from selecting data from XML. I can't seem to figure out the way xpath works with specific data selecting. Here is my XML:
<?xml version="1.0"?>
<a>
<b>
<c>Value 1</c>
<d>Value 2</d>
</b>
<b>
<c>Value 3</c>
<d>Value 4</d>
</b>
</a>
And PHP code i'm trying to use would be:
<?php
$xml = simplexml_load_file("xml.xml");
$result = $xml->xpath('b/c | b/d');
foreach ($result as $val){
echo $val['c'] . $val['d'] . "<br>;
}
If i echo $val, i get all values, however, i want to separate it so i have $val['c'] and $val['d'], like when selecting specific data from MySQL table.
Thank you in advance

You could just point to b first, then inside the loop, each b, point it to c and d:
$result = $xml->xpath('//b');
foreach ($result as $val) {
echo $val->c . $val->d . "<br>";
}

Related

How to read xml file from url with symfony [duplicate]

It looks like there are many problems with simpleXML in PHP. I'm running the latest version of php on Windows and I just can not get the basic examples of simpleXML to work as in the documentation.
My xml file is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<programme>
<title>Billy Bushwaka</title>
<episodeNumber>2</episodeNumber>
<description>Billy Bushwaka entertains</description>
<url>play.swf</url>
</programme>
My PHP program is:
<?php
$xml = simplexml_load_file("local.xml");
$result = $xml->xpath("//programme");
echo "Title: " . $result . "</br>";
?>
All I get is the following:
Title: Array
How can I get "Title: Billy Bushwaka"?
There are no repeats of XML data so I do not want to use arrays.
SimpleXML 101
First of all, always name your PHP variables after the node they represent.
// the root node is <programme/>
$programme = simplexml_load_file("local.xml");
Access to children (nodes) as if they were object properties.
echo $programme->title;
If there are multiple children using the same name, you can specify their 0-based position
// first <title/> child
echo $programme->title[0];
// create or change the value of the second <title/> child
$programme->title[1] = 'Second title';
Access to attributes as if they were array keys
// <mynode attr="attribute value" />
echo $mynode['attr'];
XPath always returns an array.
Back to your case, the best way to access that <title /> node would be
$programme = simplexml_load_file("local.xml");
echo "Title: " . $programme->title;
First of all, simplexml xpath method always returns an array of matches. Even if there is only 1 match (or even 0, in which case result is an empty array). This is why you get "Array" in the output.
Secondly, if you want just the title, then you need to change your xpath query:
$result = $xml->xpath("//programme/title");
echo "Title: " . $result[0] . "</br>";
You should probably change the xpath to //programme/title and then echo $result[0] or leave the xpath as it is and echo $result[0]->title. Remember var_dump will always help you.
I think you want:
$result = $xml->xpath("/programme/title");
echo "Title: " . $result[0] . "</br>";
$xml = simplexml_load_file("local.xml");
echo $xml->programme->title;
......
echo $xml->programme->description;

Retrieve XML element data with PHP

i'm trying to allow the user to retrieve a specific XML node and print the information. My XML data is as follows:
<people>
<person id="1">
<forename>Jim</forename>
<surname>Morrison</surname>
</person>
<person id="2">
<forename>James</forename>
<surname>Frank</surname>
</person>
</people>
I want to be able to search my XML document with a name or ID, for instance I want to be able to say, 'check that james exists, and if james does, print out his information, otherwise print out an error message'.
I've figured that I first need to include the file with:
$xml=simplexml_load_file("credentials.xml") or die("Error: Cannot create object");
From this point onwards i'm unsure how to proceed, i've looked at SimpleXML and XPATH but i'm unsure on how to use these to acheive this. Thanks if you can help
Let's xpath():
$xml = simplexml_load_string($x); // assume XML in $x
$result = $xml->xpath("/people/person[forename = 'James']")[0];
The above xpath-expression will select any <person> having 'James' as a <forename> and store it as an array in $result.
With the [0] at the end of line 2, we select only the first entry in that array and store it in $result. This requires PHP >= 5.4.
We could also write to get the same result:
$result = $xml->xpath("/people/person[forename = 'James']");
$result = $result[0];
If there were more than 1 James in the XML, we would only get the first.
To get all Jameses, do as in line 1 above.
Then, let's output the <person> selected by our xpath expression:
echo $result->forename . ' ' . $result->surname .' has id ' . $result['id'] . ".";
In case $result contains several Jameses, do:
foreach ($result as $person) {
echo $person->forename . ' ' . $person->surname .' has id ' . $person['id'] . "." . PHP_EOL;
}
see it working: https://eval.in/222195
You should use the manual.
simplexml_load_file returns a SimpleXMLElement object.
From here you can use the objects children method to get the children you want, which would also be more of that SimpleXMLElement objects. Let's say you first want the children called people, and then want person. When you got the person objects, you can get the value of the attribute by the method attributes to get the names and the values etc. Because SimpleXMLElement implements Traversable, you can use a foreach loop to loop through the lists/arrays you get in return.
Figured out how to mostly solve the problem with this:
$xml=simplexml_load_file("credentials.xml") or die("Error: Cannot create object");
foreach($xml->children() as $people){
if ($people->forename == "james" ){echo $people->forename;}
}
This may be inefficient so if anyone else has a better way please do specify :)

Showing Two elements from XML file

The file can be seen on the following URL: #
The above XML file consists of two elements which I want to be shown in order which are the "product" and "offer".
I use SimpleXML to load the XML feed.
$text = simplexml_load_file('feed.xml');
I also use foreach to show the data from the file
foreach ($text->categories->category->items->product as $product) {}
How is it possible to show the "product" and "offer" from the XML file using a for each statement or any other method?
Does <items> only ever contain <product> and <offer> elements? If so:
foreach ($text->categories->category->items->children() as $product_or_offer) {
// Do something
}
See http://php.net/simplexmlelement.children
If you want to be explicit about only ever getting the product/offer elements, a simple XPath expression could be employed.
$items = $text->categories->category->items;
$items->registerXPathNamespace('so', 'urn:types.partner.api.url.com');
foreach ($items->xpath('so:offer|so:product') as $product_or_offer) {
// Do something
}
Although I'm still don't really get what you would like to obtain I will post some examples of how to deal with this XML via xPath.
First of all select all product and offer nodes:
$xml = simplexml_load_file('feed.xml');
// Make sure to register custom namespace
$xml->registerXPathNamespace('ns', 'urn:types.partner.api.url.com');
$products = $xml->xpath('//ns:product');
$offers = $xml->xpath('//ns:offer');
echo count($products); // Number of all product nodes
echo count($offers); // Number of offer nodes
Basic iteration:
foreach ($products as $product) {
//echo '<pre>'; print_r($product); echo '</pre>';
echo '<pre>'; echo $product->name . ', ' . $product->minPrice; echo '</pre>';
}

how to get the values from this xml using dom in php?

how can i get the values of a,b and c from the following xml code?
<result name="response" f="139" c="0">
−
<doc score="5.06756" pos="0">
<snippet name="a" highlighted="yes">example</snippet>
<snippet name="b" highlighted="yes">bexample</snippet>
<snippet name="c">cexample</snippet>
</doc>
</result>
I tried to print the nodes, but It failed:
$xmlDoc = new DOMDocument();
$xmlDoc->load($content);
$x = $xmlDoc->documentElement;
foreach ($x->childNodes AS $item)
{
print $item->nodeName . " = " . $item->nodeValue . "<br />";
}
Can anyone tell me how I can parse it? I cannot use simple xml, so I am moving to Dom.
Using DOM allows you to use several distinct ways of extracting informations.
For example, you could work with :
DOMDocument::getElementsByTagName, to extract all tags having a specific name.
Or DOMXPath, for more complex queries.
As an example, here's a portion of code that demonstrates how to use the first solution to extract all <snippet> tags :
$snippets = $xmlDoc->getElementsByTagName('snippet');
foreach ($snippets as $tag) {
echo $tag->getAttribute('name') . ' = ' . $tag->nodeValue . '<br />';
}
And you'd get this output :
a = example
b = bexample
c = cexample
And, as another example, here's a solution that demonstrates how to use the second solution, to do a more complex query on the XML data -- here, extracting the <snippet> tag that as it's name attribute with a value of a :
$xpath = new DOMXPath($xmlDoc);
$snippetsA = $xpath->query('//snippet[#name="a"]');
if ($snippetsA->length > 0) {
foreach ($snippetsA as $tag) {
echo $tag->getAttribute('name') . ' = ' . $tag->nodeValue . '<br />';
}
}
Which only gets you one result -- the corresponding tag :
a = example
Starting from here, the possibilities are almost limitless ;-)

Basic simpleXML working example?

It looks like there are many problems with simpleXML in PHP. I'm running the latest version of php on Windows and I just can not get the basic examples of simpleXML to work as in the documentation.
My xml file is:
<?xml version="1.0" encoding="ISO-8859-1"?>
<programme>
<title>Billy Bushwaka</title>
<episodeNumber>2</episodeNumber>
<description>Billy Bushwaka entertains</description>
<url>play.swf</url>
</programme>
My PHP program is:
<?php
$xml = simplexml_load_file("local.xml");
$result = $xml->xpath("//programme");
echo "Title: " . $result . "</br>";
?>
All I get is the following:
Title: Array
How can I get "Title: Billy Bushwaka"?
There are no repeats of XML data so I do not want to use arrays.
SimpleXML 101
First of all, always name your PHP variables after the node they represent.
// the root node is <programme/>
$programme = simplexml_load_file("local.xml");
Access to children (nodes) as if they were object properties.
echo $programme->title;
If there are multiple children using the same name, you can specify their 0-based position
// first <title/> child
echo $programme->title[0];
// create or change the value of the second <title/> child
$programme->title[1] = 'Second title';
Access to attributes as if they were array keys
// <mynode attr="attribute value" />
echo $mynode['attr'];
XPath always returns an array.
Back to your case, the best way to access that <title /> node would be
$programme = simplexml_load_file("local.xml");
echo "Title: " . $programme->title;
First of all, simplexml xpath method always returns an array of matches. Even if there is only 1 match (or even 0, in which case result is an empty array). This is why you get "Array" in the output.
Secondly, if you want just the title, then you need to change your xpath query:
$result = $xml->xpath("//programme/title");
echo "Title: " . $result[0] . "</br>";
You should probably change the xpath to //programme/title and then echo $result[0] or leave the xpath as it is and echo $result[0]->title. Remember var_dump will always help you.
I think you want:
$result = $xml->xpath("/programme/title");
echo "Title: " . $result[0] . "</br>";
$xml = simplexml_load_file("local.xml");
echo $xml->programme->title;
......
echo $xml->programme->description;

Categories