SimpleXMLElement and getting attribute value? - php

I am having trouble getting all the data from my XML. Can any one shed some light please.
My XML is as follows
<storeitems>
<PRODUCT ITEM="3002074730">
<SPECIALS_ID>14713</SPECIALS_ID>
<FULL_PRICE>27.00</FULL_PRICE>
<SPECIALS_NEW_PRODUCTS_PRICE>25.65</SPECIALS_NEW_PRODUCTS_PRICE>
</PRODUCT>
<PRODUCT ITEM="SE-0088-10-3">
<SPECIALS_ID>29555</SPECIALS_ID>
<FULL_PRICE>53.99</FULL_PRICE>
<SPECIALS_NEW_PRODUCTS_PRICE>51.29</SPECIALS_NEW_PRODUCTS_PRICE>
</PRODUCT>
<storeitems>
My code is as follows
$xml = new SimpleXMLElement($data);
foreach($xml->PRODUCT as $post) {
echo $post->SPECIALS_ID .'<BR>';
echo $post->FULL_PRICE . '<BR>';
echo $post->SPECIALS_NEW_PRODUCTS_PRICE . '<BR>';
}
This does what I expect but can you assist me in getting this part of the XML to echo please
<PRODUCT ITEM="3002074730">

echo $post->attributes();
will print the value of your item (first) attribute (it's an object that does that when it's called in a string-context).
If you add more attributes and you want to get them all, you can iterate over $post->attributes():
foreach($post->attributes() as $name => $value){
...
}

Related

Parsing XML API data result from Plesk

I try to get domain name from Plesk API result XML data as below:
<packet version="1.6.7.0">
<site-alias>
<get>
<result>
<status>ok</status>
<info>
<name>example.com</name>
</info>
</result>
<result>
<status>ok</status>
<info>
<name>domain.net</name>
</info>
</result>
</get>
</site-alias>
</packet>
using
$xml= simplexml_load_string($response);
echo $xml['site-alias']['get']['result'][0]['name'];
if there is more better way to do so, please advice, thanks.
There are multiple ways to get the values using SimpleXMLElement.
To get only 1 value, you could for example do it like this:
// Get 1 using SimpleXMLElement
echo $xml->{"site-alias"}->get->result->info->name;
// Get 1 using xpath
echo $xml->xpath('/packet/site-alias/get/result[1]/info/name')[0];
To get multiple values you could do it like this:
// Get multiple using SimpleXMLElement
$items = $xml->{"site-alias"}->get->result;
foreach ($items as $item) {
echo $item->info->name . "<br>";
}
// Get multiple using xpath
$items = $xml->xpath('/packet/site-alias/get/result/info/name');
foreach ($items as $item) {
echo $item . "<br>";
}
The SimpleXMLElement has a method __toString so you can echo the string content.
The xpath method returns an array, so you can get the first value using index 0.
A short way to get your value could be:
echo $xml->xpath('//name')[0];
Demo

Get values XML feed by name - PHP

I'm using XML to insert products into my db with PHP. I can access / read the xml feed with the following code:
$xml=simplexml_load_file('testfeed.xml') or die("Error: Cannot create object");
foreach($xml->children() as $product) {
$pname = $product->name;
$pdescr = $product->description;
echo $pname;
echo $pdescr;
}
Below is my example XML:
<product ID="9">
<name>Product X</name>
<properties>
<property name="categoryPath">
<value>path-to-category</value>
</property>
<property name="stock">
<value>1</value>
</property>
</properties>
</product>
It's easy to get the values for name, but how do I get the value of the categorypath, since this one is inside properties->property->value and declared in the <property name="categoryPath">?
Thanks!
The easiest way without looping too much through the structures will be using XPath:
$values = $xml->xpath('//property[#name="categoryPath"]/value');
Just loop through the returned array and cast each result to string when needed, and you're done.
$xml=simplexml_load_file('./testfeed.xml') or die("Error: Cannot create object");
foreach($xml->children() as $product) {
$pname = $product->name;
$pdescr = $product->properties->property["name"];
$pdvalue = (string)$product->properties->property->value;
echo "Prdo Name: $pname\n";
echo "Prod Desc: $pdescr\n";
echo "Prod Value: $pdvalue\n";
}
Output:
Prdo Name: Product X
Prod Desc: categoryPath
Prod Value: path-to-category
Update:
While Jossif's answer is very good at getting all the nodes in bulk I'm including an edit for updated xml structure without using xpath:
$property = $product->properties->property;
$propertyAttribute = $property->attributes()->{'name'};
$catPath = ($propertyAttribute=="categoryPath")? $property->value : "value for missing paths";
print $catPath . PHP_EOL;
Since you don't seem to have any other similar xml nodes, you don't need the attribute to separate them.
You should be able to safely use this
$catPath = $product->properties->property->value;
print $catPath;
to get the string from the value node.

Getting a specific part from XML

I am trying to get the PAY where it has the ID 3 Where it says the label phone
but i really dont know how, i tried everything.
Thanks for helping!
Here is the XML code:
$books = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
<login>1</login>
<arrStatsData>
<item>
<Id>500</Id>
<Label>website_name</Label>
<Data>
<item>
<Id>4</Id>
<Label>transactions</Label>
<Data>
<sum>2029.34</sum>
<cst>47.67575</cst>
<num>86</num>
<avg>23.6</avg>
<pay>1981.66</pay>
</Data>
</item>
<item>
<Id>3</Id>
<Label>Phone</Label>
<Data>
<sum>205</sum>
<cst>17.353</cst>
<num>205</num>
<avg>1</avg>
<pay>187.647</pay>
</Data>
</item>
......
PHP Code:
$xml = simplexml_load_string($arrResult); //load xml from above
foreach($xml->arrStatsData->item->Data as $item)
{
foreach($item->item as $DATA)
{
echo $DATA->Id.'<br>';
}
My result now is:
1981.66
187.647
-0.4448
Since you know some information that's tell the node apart from the rest you can use XPath to get the value directly instead of iterating through all of them:
<?php
$sxe = new SimpleXMLElement($books);
$pay = $sxe->xpath('//item[./Id=3]/Data/pay');
echo (string) $pay[0];
Ouput:
187.647
Your PHP code would be like this:
$xml = simplexml_load_string($books);
foreach($xml->arrStatsData->item->Data as $item)
{
//echo '$item;';
foreach($item->item as $DATA)
{
if($DATA->Id == '3'){
echo $DATA->Data->pay."<br/>";
}
}
}
It retrieve the pay value when the ID is equals to 3.
Rolando Isidoro was faster to recommend xpath, my solution is slightly different, that's why I post it, too:
$pay = (string)$xml->xpath("//item[Id = '3']/Data/pay")[0];
echo $pay;
see it working: http://codepad.viper-7.com/qzPlmp

Dynamic xml handling with php

I work with many different types of xml files. I load the contents of these into my mysql database. Problem is that i need to define the tags I want to pick everytime.
Is there a php dom object functions that can iterate over all the tags and give them to me.
this is my sample xml
<products>
<product>
<name>Name of product</name>
<categories>
<category>Apparel</category>
<category>Trousers</category>
<category>Blue</category>
</categories>
<description>Blue trousers</description>
<price>599.00</price> <regularPrice>599.00</regularPrice>
</product>
</products>
Output should be NOT the values but the acctual name of the XML tags, in this case it should be
Products, Product, Name, Categories, category, description, price
Getting those values I could dynamicly point them via a connection table to always be save in the right table and in the right field.
*Try this code it will work as expected *
$xmlD = '
<products>
<product>
<name>Name of product</name>
<categories>
<category>Apparel</category>
<category>Trousers</category>
<category>Blue</category>
</categories>
<description>Blue trousers</description>
<price>599.00</price> <regularPrice>599.00</regularPrice>
</product>
</products>
';
$xml = simplexml_load_string($xmlD);
echo $xml->getName() . "<br />";
foreach($xml->children() as $child)
{
echo $child->getName(). "<br />";
foreach($child->children() as $innerChild):
echo $innerChild->getName(). "<br />";
endforeach;
}

Parsing XML data using php to put into mysql database

I have been asked to parse a simple file which is stored as an XML file, the data is to be then put into a mysql database.
However I have absolutely no clue what to do and after looking online all the examples given seem either too complicated for my problem or not the right solution. The XML file looks like this:
<shop>
<products>
<product id="1" name="Cornetto" price="1.20" description="Traditional Cornetto" />
<product id="2" name="Smarties" price="1.00" description="Smarties Icecream" />
</products>
<stocks>
<stock id="1" amount="242" price="pounds" />
<stock id="2" amount="11" price="pounds" />
</stocks>
I've tried looking at SimpleXML and I think that's the direction I have to go but I just have no idea.
Any help or pointers would be great.
I personally like the normal XMl formatting so I changed it since its a bit more readable but this is how you can use it:
$xmlstr = <<<XML
<?xml version='1.0' standalone='yes'?>
<shop>
<products>
<product>
<id>1</id>
<name>Cornetto</name>
<price>1.20</price>
<description>Traditional Cornetto</description>
</product>
<product>
<id>2</id>
<name>Smarties</name>
<price>1.00</price>
<description>Smarties Icecream</description>
</product>
</products>
<stocks>
<stock>
<id>1</id>
<amount>242</amount>
<price>pounds</price>
</stock>
<stock>
<id>2</id>
<amount>11</amount>
<price>pounds</price>
</stock>
</stocks>
</shop>
XML;
Handling part:
$xml = new SimpleXMLElement($xmlstr);
echo 'single value: <br />';
echo $xml->products->product[0]->id; // get single value
echo '<br /><br />';
//Loop trough multiple products
echo 'multiple values: <br />';
foreach($xml->products->product as $product)
{
echo $product->id.' - ';
echo $product->name.' - ';
echo $product->price.' - ';
echo $product->description;
echo '<br/>';
}
Assuming the file is called data.xml
$string = file_get_contents('data.xml') reads the entire file into $string.
$xml = new SimpleXMLElement($string); parses that string, and converts it into an object tree similar to the actual document. So if that's the document -
<root>
<b>
<c>first</c>
<c>second</c>
</b>
</root>
The SimpleXMLElement object would be used like:
$xml->b // gets all children of b (c[0] and c[1])
print $xml->b->c[0] // gets the first c, will print "first"
You can use for example SimpleXMLElement and xpath
<?php
$xmlStr = <<<EOF
<?xml version="1.0"?>
<shop>
<products>
<product id="1" name="Cornetto" price="1.20" description="Traditional Cornetto" />
<product id="2" name="Smarties" price="1.00" description="Smarties Icecream" />
</products>
<stocks>
<stock id="1" amount="242" price="pounds" />
<stock id="2" amount="11" price="pounds" />
</stocks>
</shop>
EOF;
$xml=new SimpleXMLElement($xmlStr);
// get product line with xpath for example
$products=$xml->xpath("/shop/products/product");
if ($products) {
// loop over each product node
foreach ($products as $product) {
// do whatever you want with the data
echo("id=>".$product["id"].", name=>".$product["name"]."<br/>");
}
}
// same for stock
// get product line with xpath for example
$stocks=$xml->xpath("/shop/stocks/stock");
if ($stocks) {
// loop over each product node
foreach ($stocks as $stock) {
// do whatever you want with the data
echo("id=>".$stock["id"].", amount=>".$stock["amount"]."<br/>");
}
}
?>
$xml = simplexml_load_file($filename);
foreach($xml->product as $product) {
foreach($product->attributes() as $name => $attribute) {
echo "$name = $attribute";
}
}
$xml = simplexml_load_file($filename);
foreach($xml->products->product as $not)
{
foreach($not->attributes() as $a => $b)
{
echo $a,'="',$b,"\"<br />";
}
}

Categories