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
(
...
)
)
)
SimpleXMLElementdoesn't play nice withprint_r()orvar_dump(). For example,var_dump($xml->getNamespaces());returns the namespace correctly.