Get XML element attribute with simplexml - php

I have a xml file as follows:
<?xml version="1.0" ?>
<shop version="2.0" shop-name="XYZ">
<category name="FOO1">
<subcategory name="Foobar1">
<product name="Productname1" id="1">
<supplier name="XXX" logo="XXX.gif" />
<desc>DESC</desc>
</product>
<product name="Productname2" id="2">
...
</product>
</subcategory>
</category>
</shop>
And i would like to get attribute value of shop element - exactly shop-name
I used simplexml in php:
<?php
$dataXML=simplexml_load_file("data.xml");
$a=$dataXML->shop[0]["shop-name"];
echo $a;
?>
as a result I get nothing. Have any idea what is wrong?

use the getAttribute() methdo to read attribute name.
<?php
$dataXML = simplexml_load_file("data.xml");
$shopName = $dataXML->getAttribute("shop-name");
echo $shopName;
?>

Those are attributes, so you need to access them correctly with attributes() method:
$data = simplexml_load_file( 'data.xml' );
$attributes = $data->attributes();
echo $attributes['shop-name'];
Or you can access it directly, since it's the main attribute:
$data = simplexml_load_file( 'data.xml' );
echo $data['shop-name'];

Related

How to parse XML-file to array and retrieve all children of an child with specific attribute in PHP?

my XML-file is as follows: agents.xml
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
I want to retrieve all child elements of an agent, selected by attribute value "id". I tried the following, passing a the variable "id" to the script:
$agents_xml = simplexml_load_file("/<path_to>/agents.xml");
$json = json_encode($agents_xml);
$array = json_decode($json,TRUE);
//decrement id for correct index
$id=$id-1;
//I want to return in JSON format
$testarr=json_encode($array['agent'][$id]);
echo $testarr;
When "id" has value 1, i got this:
{"#attributes":{"id":"1"},"aname":"pi1","alive":"0","scenarios":"1,2,3"}
But i know, if the XML is disordered like:
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
</agents>
This is not very reliable.
Thanks for any idea!
Try
$str = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
XML;
$xml = new SimpleXMLElement($str);
foreach($xml->agent as $agent)
{
var_dump($agent);
echo "<hr>";
}

Parse XML Parent node of matching attribute

I have an XML like the one below, I am trying to do an xpath query and parse it with simplexml. The XML is a CURL response and is stored in a $response variable. I need to look the Code attribute inside the <Item> and select the parent <Product> to parse it.
$response:
<Items>
<Product>
<Item Code="123">
</Item>
<Price>170
</Price>
</Product>
<Product>
<Item Code="456">
</Item>
<Price>150
</Price>
</Product>
</Items>
This is what I am doing:
$xml = simplexml_import_dom($response);
function loadNode($code){
global $xml;
$scode = $xml->xpath('//Item[contains(#Code,"' . $code . '")]/..');
echo $scode->Items->Product->Price;
}
loadNode("123");
This is the Notice I get:
Notice: Trying to get property of non-object
A couple of observations:
The xpath() method returns an array of SimpleXMLElement
objects, not a single SimpleXMLElement. (Yes, even though there can only be a single parent of an element, you still have to get it as the first member of the array ([0]).
$scode->Items->Product->Price should be changed to just
$scode->Price.
These modifications to your PHP code:
<?php
$response = <<<XML
<Items>
<Product>
<Item Code="123">
</Item>
<Price>170
</Price>
</Product>
<Product>
<Item Code="456">
</Item>
<Price>150
</Price>
</Product>
</Items>
XML;
$xml = simplexml_load_string($response);
function loadNode($code) {
global $xml;
$scode = $xml->xpath('//Item[contains(#Code,' . $code . ')]/..')[0];
echo $scode->Price;
}
loadNode("123");
?>
When run will yield this output:
170
as expected.

get one value from xml document in php

I have a php variable that contains xml code. I would like to get only one value from that xml and go along.
The xml is:
<?xml version="1.0" encoding="UTF-8" ?> <response> <status>SUCCESS</status> <data><count>1</count> <subscriberlist> <item> <subscriberid>4</subscriberid> <emailaddress>bbbbbb#bbbbbb.bb</emailaddress> <format>h</format> <subscribedate>1314903006</subscribedate> <confirmed>1</confirmed> <unsubscribed>0</unsubscribed> <bounced>0</bounced> <listid>3</listid> </item> </subscriberlist></data></response>
I would like to create the var $subscriberid and get the value (in this case 4)
Can someone explain me?
This doc on php.net will tell you how: http://php.net/manual/en/simplexml.examples-basic.php
For the following xml:
<?xml version="1.0" encoding="UTF-8" ?>
<response>
<status>SUCCESS</status>
<data>
<count>1</count>
<subscriberlist>
<item>
<subscriberid>4</subscriberid>
<emailaddress>bbbbbb#bbbbbb.bb</emailaddress>
<format>h</format>
<subscribedate>1314903006</subscribedate>
<confirmed>1</confirmed>
<unsubscribed>0</unsubscribed>
<bounced>0</bounced>
<listid>3</listid>
</item>
</subscriberlist>
</data>
</response>
If the xml was inside of $xmlstr then to get the subscriberid you would need the following php code:
<?php
$xml = new SimpleXMLElement($xmlstr);
$subscriberid = $xml->data->subscriberlist->item->subscriberid;
?>
You can use simplexml_load_string then parse the data
<?php
$xml = simplexml_load_string('<?xml vers...');
$subscriberid = $xml->data->subscriberlist->item->subscriberid;
?>

PHP: passing an xml node to function

i'm trying to pass an xml node to a function but can't figure out how - here's my xml markup:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<root>
<form>
<item>
<id>frm1</id>
<dbID>1</dbID>
<visible>1</visible>
</item>
</form>
<form>
<item>
<id>frm2</id>
<dbID>2</dbID>
<visible>1</visible>
</item>
</form>
</root>
when setting up a foreach loop - how's the syntax to iterate through the xml and passing the whole node to a function?
i've tried something like:
foreach($xml as $ctlXML => $value)
{
$ctl = generateCTL($ctlXML);
}
but it doesn't work as it should.
thanks
If you are using SimpleXML it is simple as
$xml = simplexml_load_file($path_to_file);
foreach($xml->form as $form){
$ctl = generateCTL($form->item);
}
Be careful - $form->item is an object

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