Reading a XML File in PHP - php

I am importing a XML file that has an amount field <amount>$10.00</amount> but when it is read in using code I got from your other posts, the value is returned as .00.
Using:
$xml = simplexml_load_file("testInput.xml");
print_r($xml);
Result:
[amount] => .00
I can't find anywhere why this is failing... Unless it has to do with the $ or period in the value field but I can't find anything about reserved characters.

I tried to duplicate your results and couldn't...
I created a file called xml_test.php:
<?php
$xml = simplexml_load_file('test_input.xml');
print_r($xml);
?>
Then built the XML (test_input.xml):
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<test>
<amount>$10.00</amount>
</test>
</tests>
And this was my result in the browser:
SimpleXMLElement Object ( [test] => SimpleXMLElement Object ( [amount] => $10.00 ) )
Is there anything else going on or am I missing something? Maybe you can paste in your XML...

Related

Parse xml from Ruby script within php failing with StartTag: invalid element name </Envelope>

I have a Ruby script which does a query to a .NET ASP server and gets the result as a string of XML;
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
<Body>
<QueryServicesResponse>
<QueryServicesResult>
<Date>2016-01-01</Date>
<serviceList>
<service>
<uuid>10264b70-87ee-11e6-ae22-56b6b6499611</uuid>
<flight>EZY0000</flight>
<originName>London Heathrow</originName>
<originShort>LHR</originShort>
<destinationName>London Stansted</destinationName>
<destinationShort>STN</destinationShort>
<scheduledDeparture>2016-01-01T14:00:00</scheduledDeparture>
<scheduledArrival>2016-01-01T14:30:00</scheduledArrival>
</service>
</serviceList>
</QueryServicesResult>
</QueryServicesResponse>
</Body>
</Envelope>
This is the section of the ruby scrip which deals with the returned body;
# Post the request
resp, data = http.post(path, data, headers)
# Output the results
doc = Nokogiri::XML(resp.body)
doc.remove_namespaces!
puts doc
The ruby script is called via a php file with the following code;
<?php
$xml = exec("ruby test.rb EZY0000",($results));
$xmlparse = simplexml_load_string($xml);
echo $xmlparse;
?>
But php Throws the following errors when trying to parse the result;
PHP Warning: simplexml_load_string(): Entity: line 1: parser error :
StartTag: invalid element name
PHP Warning: simplexml_load_string(): </Envelope>
I'm trying to parse the xml into a SimpleXMLElement Object I've been trying all sorts of things over the past few days but am stuck or blind to the problem now. I've tried htmlspecialchars but that didn't help either.
The only thing I can think of is this has something to do with the string coming from the ruby script even though it appears to be, and validates as proper xml.
If I take the xml above and use the following php code then everything works as expected and I get the desired result;
<?php
$string = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<Envelope>
<Body>
<QueryServicesResponse>
<QueryServicesResult>
<Date>2016-01-01</Date>
<serviceList>
<service>
<uuid>10264b70-87ee-11e6-ae22-56b6b6499611</uuid>
<flight>EZY0000</flight>
<originName>London Heathrow</originName>
<originShort>LHR</originShort>
<destinationName>London Stansted</destinationName>
<destinationShort>STN</destinationShort>
<scheduledDeparture>2016-01-01T14:00:00</scheduledDeparture>
<scheduledArrival>2016-01-01T14:30:00</scheduledArrival>
</service>
</serviceList>
</QueryServicesResult>
</QueryServicesResponse>
</Body>
</Envelope>
XML;
$xml = simplexml_load_string($string);
print_r($xml);
?>
Which gives me;
SimpleXMLElement Object
(
[Body] => SimpleXMLElement Object
(
[QueryServicesResponse] => SimpleXMLElement Object
(
[QueryServicesResult] => SimpleXMLElement Object
(
[Date] => 2016-01-01
[serviceList] => SimpleXMLElement Object
(
[service] => SimpleXMLElement Object
(
[uuid] => 10264b70-87ee-11e6-ae22-56b6b6499611
[flight] => EZY0000
[originName] => London Heathrow
[originShort] => LHR
[destinationName] => London Stansted
[destinationShort] => STN
[scheduledDeparture] => 2016-01-01T14:00:00
[scheduledArrival] => 2016-01-01T14:30:00
)
)
)
)
)
)
So how can I get the xml from my ruby script into a valid object which I can manipulate in php? Someome offline said I should try and do it all in Rails - but I'm not ready for anything like that much of a challenge at the moment.
So with a hint from #slowjack2k I re-looked at the Ruby file which generates the response.
doc = Nokogiri::XML(resp.body) Which I changed to become doc = Nokogiri::HTML(resp.body) and low and behold it now works and returns a valid xml object in php as expected.

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

Getting an entire value from XML

How do I get the entire result from XML using simplexml_load_string?
My XML looks like this
<xml>
<code>
<codedesc>Code Name</codedesc>
100
</code>
<code>
<codedesc>Code Name 2</codedesc>
200
</code>
</xml>
When I load it with PHP using this code
$XML = simplexml_load_string($data);
print_r($XML);
I only get codedesc and not the code number as you can see here
https://eval.in/51562
You need to wrap your values in XML so that they can be accessed.
<xml>
<code>
<codedesc>Code Name</codedesc>
<value>100</value>
</code>
<code>
<codedesc>Code Name 2</codedesc>
<value>200</value>
</code>
</xml>
You can then access them like so:
$xml = simplexml_load_string($data);
echo $xml->code[0]->value; //100
echo $xml->code[1]->value; //200
echo $xml->code[1]->codedesc; //Code Name 2
If you can't change your xml, the following should work:
echo $xml->code[0]; //100
echo $xml->code[1]; //200
I'm not sure what you're trying to get SimpleXML correctly parses your XML string, and returns a class with an array called 'code', that has 2 objects called codedesc:
SimpleXMLElement Object
(
[code] => Array
(
[0] => SimpleXMLElement Object
(
[codedesc] => Code Name
)
[1] => SimpleXMLElement Object
(
[codedesc] => Code Name 2
)
)
)
If you're trying to get to the values (100, 200) - try putting them in XML elements.
If you're trying to print the entire XML, try print_r($XML->asXML()) (see this)

xml to php conversion

I'm trying to print the response from the xml result.
<?xml version="1.0"?>
<response op="sendsmsmsg" status="400" message="Customer with mobile number 6193030168 is not opted in" version="1.0"/>
SimpleXMLElement Object
(
[#attributes] => Array
(
[op] => sendsmsmsg
[status] => 400
[message] => Customer with mobile number 6193030168 is not opted in
[version] => 1.0
)
)
how to echo the op value, status, message to this result into php
Seems like the XML is malformed. This one works. TESTED
<?php
$string = <<<XML
<?xml version='1.0' standalone='yes'?>
<response2>
<op>sendsmsmsg</op>
<status>400</status>
<message>Customer with mobile number 6193030168 is not opted in</message>
</response2>
XML;
$xml = new SimpleXMLElement($string);
echo $xml->op."<br>".$xml->status."<br>".$xml->message;
?>
OUTPUT
sendsmsmsg
400
Customer with mobile number 6193030168 is not opted in
i have tested it with your xml :
//data.xml has
<?xml version="1.0"?>
<response op="sendsmsmsg" status="400" message="Customer with mobile number 6193030168 is not opted in" version="1.0"/>
<?php
$xml = simplexml_load_file('data.xml');
print($xml['op']);
?>

Getting cdata content while parsing xml file

I have an xml file
<?xml version="1.0" encoding="utf-8"?>
<xml>
<events date="01-10-2009" color="0x99CC00" selected="true">
<event>
<title>You can use HTML and CSS</title>
<description><![CDATA[This is the description ]]></description>
</event>
</events>
</xml>
I used xpath and and xquery for parsing the xml.
$xml_str = file_get_contents('xmlfile');
$xml = simplexml_load_string($xml_str);
if(!empty($xml))
{
$nodes = $xml->xpath('//xml/events');
}
i am getting the title properly, but iam not getting description.How i can get data inside
the cdata
SimpleXML has a bit of a problem with CDATA, so use:
$xml = simplexml_load_file('xmlfile', 'SimpleXMLElement', LIBXML_NOCDATA);
if(!empty($xml))
{
$nodes = $xml->xpath('//xml/events');
}
print_r( $nodes );
This will give you:
Array
(
[0] => SimpleXMLElement Object
(
[#attributes] => Array
(
[date] => 01-10-2009
[color] => 0x99CC00
[selected] => true
)
[event] => SimpleXMLElement Object
(
[title] => You can use HTML and CSS
[description] => This is the description
)
)
)
You are probably being misled into thinking that the CDATA is missing by using print_r or one of the other "normal" PHP debugging functions. These cannot see the full content of a SimpleXML object, as it is not a "real" PHP object.
If you run echo $nodes[0]->Description, you'll find your CDATA comes out fine. What's happening is that PHP knows that echo expects a string, so asks SimpleXML for one; SimpleXML responds with all the string content, including CDATA.
To get at the full string content reliably, simply tell PHP that what you want is a string using the (string) cast operator, e.g. $description = (string)$nodes[0]->Description.
To debug SimpleXML objects and not be fooled by quirks like this, use a dedicated debugging function such as one of these: https://github.com/IMSoP/simplexml_debug
This could also be another viable option, which would remove that code and make life a little easier.
$xml = str_replace("<![CDATA[", "", $xml);
$xml = str_replace("]]>", "", $xml);

Categories