simplexml_load_string and simplexml_load_file are buggy and don't work well on XML with a complex markup.
I tried both functions to parse some VALID XML SOAP responses and could not even get an error message.
I had to use DOMDocument instead (worked like a charm).
Here is how we suppose to check simplexml for errors (if you are lucky to see errors, not just "false" returned from function)
libxml_use_internal_errors(true);
$xml=simplexml_load_string($myXMLData); //or simplexml_load_file
foreach( libxml_get_errors() as $error ) {
print_r($error);
}
Answer from vitaly goji on Stack Overflowsimplexml_load_string and simplexml_load_file are buggy and don't work well on XML with a complex markup.
I tried both functions to parse some VALID XML SOAP responses and could not even get an error message.
I had to use DOMDocument instead (worked like a charm).
Here is how we suppose to check simplexml for errors (if you are lucky to see errors, not just "false" returned from function)
libxml_use_internal_errors(true);
$xml=simplexml_load_string($myXMLData); //or simplexml_load_file
foreach( libxml_get_errors() as $error ) {
print_r($error);
}
I could find an answer to my question with a small workaround. simplexml_load_string() continuously displayed encoding errors. So I used simplexml_load_file() as bellow. I've saved the file in to local location and then load with simplexml_load_file().
$tempLocalPath = "temp/data.xml";
file_put_contents($tempLocalPath, $s3Data);
$xml = simplexml_load_file($tempLocalPath);
However still I don't understan why simplexml_load_string() couldn't parse the same thing.
xml - PHP: Call to undefined function: simplexml_load_string() - Stack Overflow
simplexml_load_string function not loading XML file in PHP - Stack Overflow
The simplexml_load_string command in the php file does not work
php - Issue with simplexml_load_string() - Stack Overflow
Videos
For PHP 7 and Ubuntu 14.04 the procedure is follows. Since PHP 7 is not in the official Ubuntu PPAs you likely installed it through Ondřej Surý's PPA (sudo add-apt-repository ppa:ondrej/php). Go to /etc/php/7.0/fpm and edit php.ini, uncomment to following line:
extension=php_xmlrpc.dll
Then simply install php7.0-xml:
sudo apt-get install php7.0-xml
And restart PHP:
sudo service php7.0-fpm restart
And restart Apache:
sudo service apache2 restart
If you are on a later Ubuntu version where PHP 7 is included, the procedure is most likely the same as well (except adding any 3rd party repository).
If the XML module is not installed, install it.
Current version 5.6 on ubuntu 14.04:
sudo apt-get install php5.6-xml
And don't forget to run sudo service apache2 restart command after it
Zulhilmi Zainudi
This errors means you do not have the simpleXML library loaded with PHP.
You should print your phpinfo() in Command Line mode and check the presence of the simplexml library.
Check then how to install the simplexml library on your OS.
The error output is common when php-xml extension is not installed (or unavailable) for the PHP CLI.
To fix it, install php-xml (for your version of PHP) using:
For PHP 5.4
sudo apt-get install php5-xml
For PHP 5.6
sudo apt-get install php5.6-xml
Then restart php5-fpm
sudo service php5-fpm restart
After installation of php-xml, if you encounters such as:
Zend_Db_Adapter_Exception' with message 'pdo_mysql extension is not installed' in /var/www/magento/lib/Varien/Db/Adapter/Pdo/Mysql.php
Then, install pdo-mysql and php5-gd For PHP 5.4
sudo apt-get install php5-gd php5-mysql
For PHP 5.6
sudo apt-get install php5.6-gd php5.6-mysql
Then restart php5-fpm
sudo service php5-fpm restart
To answer your question, let's first examine the problem.
Problem
Assuming you are displaying the contents of your $xml variable through:
php > print_r($xml);
Here, you are listing the children of the current node (the root node) with the default namespace (without prefix) which is not declared in that node:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.beautyfort.com/api/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
If you would list the namespaces of that node:
php > print_r($xml->getNamespaces());
Array
(
[SOAP-ENV] => http://schemas.xmlsoap.org/soap/envelope/
)
there is only a single one visible, because that is the only one actually used in that (root) node excluding its children.
To list all used namespaces of the root and all its children add 'true' as first argument:
php > print_r($xml->getNamespaces(true));
Array
(
[SOAP-ENV] => http://schemas.xmlsoap.org/soap/envelope/
[ns1] => http://www.beautyfort.com/api/
[xsi] => http://www.w3.org/2001/XMLSchema-instance
)
To list all declared namespaces of the root and all its children:
php > print_r($xml->getDocNamespaces(true));
Array
(
[SOAP-ENV] => http://schemas.xmlsoap.org/soap/envelope/
[ns1] => http://www.beautyfort.com/api/
[xsi] => http://www.w3.org/2001/XMLSchema-instance
)
Solution #1
simplexml_load_string allows to set a default namespace as argument, e.g. SOAP-ENV (with extra argument to indicate that it is a prefix):
php > $xml = simplexml_load_string($content, "SimpleXMLElement", 0, "SOAP-ENV", true);
If you now print your variable, you will get closer to what you need:
php > print_r($xml);
SimpleXMLElement Object
(
[Body] => SimpleXMLElement Object
(
)
)
But this only holds for the root node.
When listing children, you still need to specify a namespace if the children use namespaces other than the default (empty) one, and indicate whether its a prefix or namespace:
php > print_r($xml->children("SOAP-ENV", true));
SimpleXMLElement Object
(
[Body] => SimpleXMLElement Object
(
)
)
To see the children of the first root child do the following:
php > print_r($xml->children("SOAP-ENV", true)->children("ns1", true));
SimpleXMLElement Object
(
[ProductSearchResponse] => SimpleXMLElement Object
(
...
)
)
But this might not be what you are looking for, as it is not a generic solution.
Solution #2
Use a string replace for all your namespaces and reload the XML document (stored in $content):
php > $content2 = str_replace(array_map(function($e) { return "$e:"; }, array_keys($xml->getDocNamespaces())), array(), $content);
Your input XML now looks like this:
php > echo $content2;
<?xml version="1.0" encoding="UTF-8"?><Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.beautyfort.com/api/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Body><ProductSearchResponse><TestMode>false</TestMode><Page>1</Page><ResultsPerPage>1</ResultsPerPage><TotalResults>1276</TotalResults><Items><Item><StockCode>L3720</StockCode><Name>David Beckham Instinct Gift Set 30ml EDT + 150ml Shower Gel</Name><QuantityAvailable>1</QuantityAvailable><UnitPrice Currency="GBP"><Amount>8.72</Amount></UnitPrice><YourRating nil="true"/><YourStockCode></YourStockCode><ImageLastUpdated>2016-12-22 18:13:08</ImageLastUpdated><ThumbnailImageUrl>https://www.beautyfort.com/pic/Y0NqeTBJbmdvaUx6ZUFOa0MyTlNObmhGckltYnVQQmg%3D</ThumbnailImageUrl><HighResImageUrl nil="true"/></Item></Items></ProductSearchResponse></Body></Envelope>
Reload and print:
php > $xml2 = simplexml_load_string($content2);
php > print_r($xml2);
SimpleXMLElement Object
(
[Body] => SimpleXMLElement Object
(
[ProductSearchResponse] => SimpleXMLElement Object
(
...
)
)
)
The output your getting is just not helpful more than incorrect. When dealing with SimpleXML and DOMDocument, there structure is quite complex and you don't always get all the information.
When using SimpleXML - the best way of seeing the content of a node is to use asXML(), which recreates the original XML of the node.
$xml = simplexml_load_string($response);
echo $xml->asXML();
This give you your original content.
Running php7.2-fpm on Debian 10.
I have installed php7.2-xml and in phpinfo() I can see it (/etc/php/7.2/fpm/conf.d/20-simplexml.ini,)
But still when I fire script it throught thsi error. Please help ! I am getting crazy!