SimpleXML showing unexpected behaviour - php

I have a XML file named conf.xml and I'm trying to display the contents of this XML file via a simple php script (placed in the same directory) as follows:
conf.xml
<?xml version="1.0" encoding="UTF-8"?>
<registration_info>
<organization name="Home" />
</registration_info>
PHP script:
$data=simplexml_load_file("conf.xml");
$node=$data->registration_info;
$subnode=$node->organization;
echo (string) $subnode['name']; // Displays null string
I feel that there's nothing wrong with the code but the output is unexpected as the anticipated output was "Home". Can anyone please help me solve this problem and explain me the solution?
Thanks in advance.

The existing answer given here is correct, but the explanations are rather confused. SimpleXML is not hiding the root node of your XML, it's just that the object you have already is that node.
Each SimpleXMLElement object represents a particular node in the XML document's tree. There is no separate object in SimpleXML representing "the whole document", so when you run simplexml_load_file, the object returned is the SimpleXMLElement for the root node.
$root_node = simplexml_load_file("conf.xml");
echo $root_node->getName(); // registration_info
$child_node = $root_node->organization;
// Short for $root_node->organization[0];
// meaning "get the first child with name 'organization'
echo $child_node->getName(); // organization

Try this hope this will help you out. You have to just remove $node=$data->registration_info;
Try this snippet here
<?php
ini_set('display_errors', 1);
$data=simplexml_load_file("conf.xml");
$subnode=$data->organization;
echo (string) $subnode['name'];
Output: print_r($data)
SimpleXMLElement Object
(
[organization] => SimpleXMLElement Object
(
[#attributes] => Array
(
[name] => Home
)
)
)

Related

How to get attribute value from xml? [duplicate]

This question already has answers here:
How to retrieve data from # xml attribute in PHP
(2 answers)
Closed 8 years ago.
I saw lot of examples but nothing is working perfectly. This is the array i got after parsing.
SimpleXMLElement Object
(
[#attributes] => Array
(
[areaUnits] => acre
)
)
Now i try to get attributes,like this:
var_dump($list->attributes());
I got this error:
var_dump(): Node no longer exists
<?php
function xml_attribute($object, $attribute)
{
if(isset($object[$attribute]))
return (string) $object[$attribute];
}
print xml_attribute($xml, 'areaUnits'); //prints "acre"
?>
Obtaining the attributes of a SimpleXMLElement is very straight forward.
The XML:
<?xml version="1.0"?>
<root>
<node attribute1="value1" attribute2="value2">data</node>
</root>
The PHP:
// assume $xml variable contains the XML document above
$sxe = new SimpleXMLElement($xml)
$value1 = $sxe->node->attributes()->attribute1;
$value2 = $sxe->node->attributes()->attribute2;
In your example above, $list MUST reference an actual XML node in order for you to attempt to access its attributes. Based on your error, it sounds like you're not doing that, which can often happen if you modify the XML structure referenced by $list at run time.

How to get name of very first tag of XML with php's SimpleXML?

I am parsing XML strings using simplexml_load_string(), but I noticed that i don't get the name of the very first tag.
For example, I have these two xml strings:
$s = '<?xml version="1.0" encoding="UTF-8"?>
<ParentTypeABC>
<chidren1>
<children2>1000</children2>
</chidren1>
</ParentTypeABC>
';
$t = '<?xml version="1.0" encoding="UTF-8"?>
<ParentTypeDEF>
<chidren1>
<children2>1000</children2>
</chidren1>
</ParentTypeDEF>
';
NOTICE that they are nearly identical, the only difference being that one has the first node as <ParentTypeABC> and the other as <ParentTypeDEF>
then I just convert them to SimpleXML objects:
$o = simplexml_load_string($s);
$p = simplexml_load_string($t);
but then i have two equal objects, none of them having the "top" node's name appearing, either ParentTypeABC or ParentTypeDEF (I examine the objects using print_r()):
// with top node "ParentTypeABC"
SimpleXMLElement Object
(
[chidren1] => SimpleXMLElement Object
(
[children2] => 1000
)
)
// with top node "ParentTypeDEF"
SimpleXMLElement Object
(
[chidren1] => SimpleXMLElement Object
(
[children2] => 1000
)
)
So how I am supposed to know the top node's name? If I parse unknown XMLs and I need to know what's the top node name, what can I do?
Is there an option in simplexml_load_string() I could use?
I know there are MANY ways to parse XML's with PHP, but I'd like it to be as simple as posible, and to get a simple object or array I could navigate easily.
I made a simple example here to fiddle with.
SimpleXML has a getName() method.
echo $xml->getName();
This should return the name of the respective node, no matter if root or not.
http://php.net/manual/en/simplexmlelement.getname.php

file_get_contents() warning when load xml data

what i want to do is : i have an CRM API which produce data in xml format,
i am using DOMDocument() to fetch the data into pieces. The problem is when i tried to load the data like : $dom->loadXML($data);
i got the error :
DOMDocument::loadXML() [domdocument.loadxml]: Input is not proper UTF-8
i google i got an alternative solution to use with file_get_contents() but still i am getting warning like:
here is the code that i am using to fetch the xml data:
$text = file_get_contents(stripslashes(utf8_decode($data)));
$doc = new DOMDocument();
$doc->loadXML($text);
and here i put my XML return data, not complete but just a small piece:
<?xml version="1.0" encoding="utf-8"?>
<whmcsapi version="5.0.3">
<action>getticket</action>
<result>success</result>
<ticketid>5767</ticketid>
<tid>409865</tid>
<c>NwLldOG6</c>
<deptid>2</deptid>
<deptname>Technical</deptname>
<userid>27476</userid>
<name>shirley b broyles (home)</name>
<email>sbroyles1#stx.rr.com</email>
<cc></cc>
<date>2012-08-27 19:52:12</date>
<subject>printer not working</subject>
<status>Customer-Reply</status>
<priority>High</priority>
<admin></admin>
<lastreply>2012-08-28 23:34:17</lastreply>
<flag>0</flag>
<service></service>
<replies>
<reply>
can anyone please tell me where is the problem? or any alternative ??
Okay, so let's strip down the problem. If $data contains invalid UTF-8, you should be thinking how to make it valid; one way (not sure if that works for you) is with utf8_encode() rather than utf8_decode() (which is used to turn UTF-8 into ISO-8859-1):
$doc = new DOMDocument();
$doc->loadXML(utf8_encode($data));
Otherwise you will need to find out which part of the text includes the bad input. I'll see what I can come up with.
Resources
Ensuring valid utf-8 in PHP
you can try simplexml_load_file php function..
$xml = simplexml_load_file("addinsrss.xml");
echo "<pre>";print_r($xml);echo "</pre>";
If you already have the xml source then dont pass it to FGC. Pass it directly to domDocument.
Or you can also use simplexml_load_string(),
<?php
$xml = '<?xml version="1.0" encoding="utf-8"?>
<whmcsapi version="5.0.3">
<action>getticket</action>
<result>success</result>
<ticketid>5767</ticketid>
<tid>409865</tid>
<c>NwLldOG6</c>
<deptid>2</deptid>
<deptname>Technical</deptname>
<userid>27476</userid>
</whmcsapi>
';
$xml = simplexml_load_string($xml);
print_r($xml);
/*
SimpleXMLElement Object
(
[#attributes] => Array
(
[version] => 5.0.3
)
[action] => getticket
[result] => success
[ticketid] => 5767
[tid] => 409865
[c] => NwLldOG6
[deptid] => 2
[deptname] => Technical
[userid] => 27476
...
...
)
*/
echo $xml->tid; //409865
?>
Or directly use $xml = simplexml_load_file('http://example.com/somexml.xml'); to load from an external url.

Breaking up an XML file

I've got an XML output that produces code such as:
<loadavg>
<one>0.00</one>
<five>0.02</five>
<fifteen>0.02</fifteen>
</loadavg>
<!-- whostmgrd -->
I would like to know how I can use PHP to parse that file, and grab the contents between <one>,<five> and <fifteen>. It would be useful if it were to be stored as $loadavg[1] an array.
Thanks
Yep, SimpleXML can do it:
$xml = <<<XML
<loadavg>
<one>0.00</one>
<five>0.02</five>
<fifteen>0.02</fifteen>
</loadavg>
XML;
$root = new SimpleXMLElement($xml);
$loadavg = array((string) $root->one,
(string) $root->five,
(string) $root->fifteen);
print_r($loadavg);
prints
Array (
[0] => 0.00
[1] => 0.02
[2] => 0.02
)
The easiest way to parse an XML file is using SimpleXML. It should be easy to load the XML as a SimpleXML object and get the data using that. If you could post a sample of a complete XML file I could offer some sample code.

PHP SimpleXML with xpath

I have a small XML file:
<wddxPacket version='1.0'>
<header/>
<data>
<struct type='coldfusion.runtime.ArgumentCollection'>
<var name='HEADLINE'>
<string>Richard Barret's Articles on Leadership and High Performance Organisations</string>
</var>
</struct>
</data>
</wddxPacket>
I'm trying to use PHP SimpleXML and xpath to extract the value between the string element in the var name HEADLINE element. This code works:
// Location of the XML file on the file system
$file = 'http://10.10.200.37/skins/importscript/41802.xml';
$xml = simplexml_load_file($file);
// CREATE THE ARRAYS FOR EACH XML ELEMENT NEEDED
$title = $xml->xpath('//var[#name="HEADLINE"]');
echo "<p>";
print_r($title);
echo "</p>";
The problem is that it returns not only the value but also all the array information. As in:
Array (
[0] => SimpleXMLElement Object (
[#attributes] => Array (
[name] => HEADLINE
)
[string] => Richard Barret's Articles on Leadership and High Performance Organisations
)
)
How can I get it to return just the value and nothing else?
If I replace print_r with echo $title; I get the word Array on the page instead of the value. If I try echo $title[0]; I get nothing at all.
I've tried so many things now can't think of anything else! What am I doing wrong? Could anyone point me in the right direction? Thanks!
Sorry please ignore this!
Just after I posted the question I realised what I was doing wrong!
For anyone being as slow as I am today here was the problem...
$title = $xml->xpath('//var[#name="HEADLINE"]');
Should be:
$title = $xml->xpath('//var[#name="HEADLINE"]/string');
Now it works as it should.
You are interested in the nodeValue.
Example:
$xpath->evaluate("some_tag_name", $some_dom_element)->item(0)->nodeValue;
or use the string selector:
$title = $xml->xpath('//var[#name="HEADLINE"]/string');
As a habit I always add the 'string' type when getting values from SimpleXML
$title = (string) $xml->xpath('//var[#name="HEADLINE"]/string');
Not sure if this is good practice..

Categories