Reading XML with PHP. Not work (namespaces) - php

I can read XML files or strings but not the next:
$str = <<<XML
<Output xmlns="nice.uniform://" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Data i:nil="true"/>
<Result xmlns:a="http://nice.uniform/CLSAPI3">
<a:ResultCode>SUCCESS</a:ResultCode>
<a:ResultMessage>OK</a:ResultMessage>
<a:ResultCodeEx>CLS_SE_SUCCESS</a:ResultCodeEx>
</Result>
<Exception i:nil="true" xmlns:a="http://schemas.datacontract.org/2004/07/System"/>
</Output>
XML;
My PHP code to read a node of XML file is:
$Output = new SimpleXMLElement($str);
echo $Output->Result->{'a:ResultCodeEx'};
Also, I've tried:
$xmlResponse = simplexml_load_file('file.xml');
foreach($xmlResponse->Result as $xmlEntry)
{
echo $xmlEntry->{'a:ResultCodeEx'};
}
//or
$blocks = $xmlResponse->xpath('//Output');
print_r($blocks);
Can you help me?

The document uses several namespaces. The element ResultCodeEx belongs to the namespace a. You can use XPath, but you need to register the namespace a before the query:
$Output = new SimpleXMLElement($str);
$Output->registerXPathNamespace ('a', 'http://nice.uniform/CLSAPI3');
$result = $Output->xpath('//a:ResultCodeEx/text()');
echo $result[0]; // CLS_SE_SUCCESS

Related

SOAP XML to PHP Array

I'm using $data = file_get_contents('php://input'); when a service is posting xml data to my url. It's giving me an xml string, but I can't figure out how to turn it into a php array. I've tried every solution I can find here on Stack, and it always gives me an empty array. Here's the xml:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Authentication xmlns="urn:www.blank.com:blank:services:2:0:wsdl">
<username></username>
<password></password>
</Authentication>
</soap:Header>
<soap:Body>
<TransferDataString xmlns="urn:www.blank.com:blank:services:2:0:wsdl">
<data>
<?xml version="1.0"?>
<AssessmentResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId idOwner="Blank">
<IdValue name="ReceiptID">2461fg453f99-ea45dsg55-448464-85fgd80-e45fg77e5568b7f1</IdValue>
<IdValue name="bID">1422255467627</IdValue>
</ReceiptId>
<ClientOrderId idOwner="BlankPartner" />
<Results>
<Profile>Blank Credits</Profile>
<SupportingMaterials>
<Description>No Forms Needed</Description>
</SupportingMaterials>
<OverallResult>
<Description>Initial Eligibility</Description>
<Score type="PotentialBlank1Eligibility">0</Score>
<Score type="PotentialBlank2Eligibility">0</Score>
</OverallResult>
<DetailResult>
<Score type="Eligibility">0</Score>
</DetailResult>
</Results>
<AssessmentStatus>
<Status>Completed</Status>
<Details>No Errors</Details>
<StatusDate>2017-12-20T14:31:04.287072-05:00</StatusDate>
</AssessmentStatus>
</AssessmentResult>
</data>
</TransferDataString>
</soap:Body>
</soap:Envelope>
I've replaced some words with "blank" for obscurity.
I've tried the recursive xml2array() functions floating about (here, for instance). Returns empty array.
I've tried:
$xml = simplexml_load_string($string, "SimpleXMLElement", LIBXML_NOCDATA);
$array = json_decode(json_encode((array)$xml), TRUE);
Empty array.
What am I missing?
UPDATE
I am now getting this string:
<?xml version="1.0"?>
<AssessmentResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://ns.hr-xml.org/2007-04-15">
<ReceiptId idOwner="Blank">
<IdValue name="ReceiptID">2461fg453f99-ea45dsg55-448464-85fgd80-e45fg77e5568b7f1</IdValue>
<IdValue name="bID">1422255467627</IdValue>
</ReceiptId>
<ClientOrderId idOwner="BlankPartner" />
<Results>
<Profile>Blank Credits</Profile>
<SupportingMaterials>
<Description>No Forms Needed</Description>
</SupportingMaterials>
<OverallResult>
<Description>Initial Eligibility</Description>
<Score type="PotentialBlank1Eligibility">0</Score>
<Score type="PotentialBlank2Eligibility">0</Score>
</OverallResult>
<DetailResult>
<Score type="Eligibility">0</Score>
</DetailResult>
</Results>
<AssessmentStatus>
<Status>Completed</Status>
<Details>No Errors</Details>
<StatusDate>2017-12-20T14:31:04.287072-05:00</StatusDate>
</AssessmentStatus>
</AssessmentResult>
from this method:
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $string);
$xml = new SimpleXMLElement($response);
$body = $xml->xpath('//soapBody')[0];
$array = json_decode(json_encode((array)$body), TRUE);
$data = $array['TransferDataString']['data'];
var_dump($data);
But I cannot figure out how to convert that string to a PHP array.
To access the inner data elements...
$xml = simplexml_load_string($data);
$xml->registerXPathNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$data = $xml->xpath("//soap:Body");
$innerData = (string)$data[0]->TransferDataString->children("urn:www.blank.com:blank:services:2:0:wsdl")->data;
// Convert data to array
$xml2 = simplexml_load_string(trim($innerData));
$array = json_decode(json_encode($xml2), true);
print_r($array);
You can then process the data either as XML, or convert it to an array.
The first part extracts the soap:Body and then it manipulates that to get at the final inner content.
Example:
$dom = new DOMDocument("1.0", "UTF-8");
$dom->preserveWhiteSpace = false;
$dom->loadXml($source);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
$xpath->registerNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
$xpath->registerNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
$xpath->registerNamespace("xmlns", "urn:www.blank.com:blank:services:2:0:wsdl");
// Read the data element
$data = $xpath->query('//soap:Body/xmlns:TransferDataString/xmlns:data')->item(0)->nodeValue;
$data = trim($data);
echo $data;

Parsing xml response from ebay getsellerlist with php

I am trying to parse XML with PHP. The XML is a response from ebay getsellerlist api, and is structured like so:
<!--?xml version="1.0" encoding="UTF-8"?-->
<getsellerlistresponse xmlns="urn:ebay:apis:eBLBaseComponents">
<timestamp>2016-08-11T14:17:39.869Z</timestamp>
<ack>Success</ack>
<version>967</version>
<build>E967_CORE_APISELLING_17965876_R1</build>
<itemarray>
<item>
<itemid>itemid1</itemid>
<listingdetails>
<viewitemurl>itemurl1</viewitemurl>
</listingdetails>
<primarycategory>
<categoryid>categoryid1</categoryid>
<categoryname>categoryname1</categoryname>
</primarycategory>
<title>title1</title>
<picturedetails>
<galleryurl>url1</galleryurl>
<photodisplay>thumbnail1</pictureurl>
<pictureurl>picture1</pictureurl>
</picturedetails>
</item>
</itemarray>
</getsellerlistresponse>
My php is as follows:
<?
$xml = '<!--?xml version="1.0" encoding="UTF-8"?--><getsellerlistresponse xmlns="urn:ebay:apis:eBLBaseComponents"><timestamp>2016-08-11T14:17:39.869Z</timestamp><ack>Success</ack><version>967</version><build>E967_CORE_APISELLING_17965876_R1</build><itemarray><item><itemid>itemid1</itemid><listingdetails><viewitemurl>itemurl1</viewitemurl></listingdetails><primarycategory><categoryid>categoryid1</categoryid><categoryname>categoryname1</categoryname></primarycategory><title>title1</title><picturedetails><galleryurl>url1</galleryurl><photodisplay>thumbnail1</pictureurl><pictureurl>picture1</pictureurl></picturedetails></item><item><itemid>itemid2</itemid><listingdetails><viewitemurl>itemurl2</viewitemurl></listingdetails><primarycategory><categoryid>categoryid2</categoryid><categoryname>categoryname2</categoryname></primarycategory><title>title1</title><picturedetails><galleryurl>url2</galleryurl><photodisplay>thumbnail2</pictureurl><pictureurl>picture2</pictureurl></picturedetails></item></itemarray></getsellerlistresponse>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$title_nodes = $dom->getElementsByTagName('title');
$titles = array();
foreach ($title_nodes as $node) {
$titles[] = $node->nodeValue;
echo $node->nodeValue;
}
echo $titles[0];
echo count($titles);
?>
When I run it, I get a blank page, no errors, nothing.
If I check $titles length using count(), it comes back as zero.
For some reason it is not getting the title node (or any other nodes) and I can't figure out how to parse the xml string with php and get the node values.
Any help most appreciated, if the question is vague or lacking detail, please let me know and I will correct it.
The XML isn't valid:
Unable to parse any XML input. org.jdom2.input.JDOMParseException: Error on line 2: The element type "photodisplay" must be terminated by the matching end-tag "".
And that's only after you remove the comments in your XML declaration:
<!--?xml version="1.0" encoding="UTF-8"?-->
shoud be
<?xml version="1.0" encoding="UTF-8"?>
Working demo:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<getsellerlistresponse xmlns="urn:ebay:apis:eBLBaseComponents">
<timestamp>2016-08-11T14:17:39.869Z</timestamp>
<ack>Success</ack>
<version>967</version>
<build>E967_CORE_APISELLING_17965876_R1</build>
<itemarray>
<item>
<itemid>itemid1</itemid>
<listingdetails>
<viewitemurl>itemurl1</viewitemurl>
</listingdetails>
<primarycategory>
<categoryid>categoryid1</categoryid>
<categoryname>categoryname1</categoryname>
</primarycategory>
<title>title1</title>
<picturedetails>
<galleryurl>url1</galleryurl>
<photodisplay>thumbnail1</photodisplay>
<pictureurl>picture1</pictureurl>
</picturedetails>
</item>
</itemarray>
</getsellerlistresponse>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$title_nodes = $dom->getElementsByTagName('title');
$titles = array();
foreach ($title_nodes as $node) {
$titles[] = $node->nodeValue;
echo $node->nodeValue;
}
echo $titles[0];
echo count($titles);

PHP XML: how to use createCDataSection() properly

I am trying to create an xml dynamically using domDocument.
What I would like to obtain is following:
<?xml version="1.0"?>
<books>
<book>
<content>
<name><![CDATA[dddd]]></name>
</content>
</book>
</books>
Unfortunatelly the script below does not show the output as excepted.
$xml = new DOMDocument('1.0');
$xml->formatOutput = true;
$books = $xml->createElement('books');
$xml->appendChild($books);
$book = $xml->createElement('book');
$books->appendChild($book);
$inside = $xml->createElement('content');
$book->appendChild($inside);
$xml->appendChild($inside)->appendChild($xml->createElement('name'))->appendChild($xml->createCDataSection('dddd'));
echo '<xmp>'.$xml->saveXML().'</xmp>';
This is the output
<?xml version="1.0"?>
<books>
<book>
<content>
<name><![CDATA[dddd]]></name>
<lastname><![CDATA[dddd]]></lastname>
....
</content>
I do not know how to use createCDataSection().
Like this?
$xml = new DOMDocument('1.0');
$xml->formatOutput = true;
$books = $xml->createElement('books');
$xml->appendChild($books);
$book = $xml->createElement('book');
$books->appendChild($book);
$content = $xml->createElement('content');
$book->appendChild($content);
$name = $xml->createElement('name');
$content->appendChild($name);
$name->appendChild($xml->createCDataSection('dddd'));
echo '<xmp>'.$xml->saveXML().'</xmp>';

Generate XML using PHP

I have the following PHP code from which I need to generate XML.
$hparams["SiteName"]="";
$hparams["AccountCode"]="";
$hparams["UserName"]='xxxx';
$hparams["Password"]='xxxx';
$client_header = new SoapHeader('url','AuthenticationData',$hparams,false);
$cliente = new SoapClient($wsdl); $cliente->__setSoapHeaders(array($client_header));
$opta=array();
$opta["Search"]["request"]["Origin"]="MAA";
$opta["Search"]["request"]["Destination"]="BOM";
$opta["Search"]["request"]["DepartureDate"]="2014-05-20T00:00:00";
$opta["Search"]["request"]["ReturnDate"]="2014-05-22T00:00:00";
$opta["Search"]["request"]["Type"]="OneWay";
$opta["Search"]["request"]["CabinClass"]="All";
$opta["Search"]["request"]["PreferredCarrier"]="";
$opta["Search"]["request"]["AdultCount"]="1";
$opta["Search"]["request"]["ChildCount"]="0";
$opta["Search"]["request"]["InfantCount"]="0";
$opta["Search"]["request"]["SeniorCount"]="0";
$opta["Search"]["request"]["IsDirectFlight"]="true";
$opta["Search"]["request"]["PromotionalPlanType"]="Normal";
$h=array();
$h= (array)$cliente->__call('Search',$opta);
How can I generate an XML of the above variables in PHP ?
The format should be
<xml>
<credential>
<Sitename>sitename</Sitename>
<AccountCode>ACC Code</AccountCode>
</credentials>
<Data>
<Origin>MAA</Origin>
<Destination>BOM</Destination>
</Data>
</xml>
Any help would be appreciate.
Thank you.
<?php
ini_set('error_reporting', E_ALL);
$dom = new DomDocument('1.0'); // making xml
$credentials = $dom->appendChild($dom->createElement('Credentials')); // adding root element <credentials>
$sitename = $credentials->appendChild($dom->createElement('Sitename')); // adding element <sitename> in <credentials>
$accountcode = $credentials->appendChild($dom->createElement('AccountCode')); // adding element <accountcode> in <credentials>
$sitename->appendChild($dom->createTextNode('sitename')); // adding text in <sitename>
$accountcode->appendChild($dom->createTextNode('ACC Code')); // adding text in <accountcode>
$data = $dom->appendChild($dom->createElement('Data'));
$origin = $data->appendChild($dom->createElement('Origin'));
$destination = $data->appendChild($dom->createElement('Destination'));
$origin->appendChild($dom->createTextNode('MAA'));
$destination->appendChild($dom->createTextNode('BOM'));
$dom->formatOutput = true; // generating xml
// generating XML as string or file
$test1 = $dom->saveXML();
$dom->save('test1.xml');
?>
I think you could write loop by yourself ;)
P.S. PHP 5+
First of all, your xml is not well structured.
It should be like:
<xml>
<credentials>
<Sitename>sitename</Sitename>
<AccountCode>ACC Code</AccountCode>
<Data>
<Origin>MAA</Origin>
<Destination>BOM</Destination>
</Data>
</credentials>
<credentials>
...
</credentials>
</xml>
Iterate the obtained result, and by concating , form the needed xml.

XML creation on the fly using PHP

I have a small requirement where I need to create a XML file on the fly. It was no problem for me to create a normal xml file which would be looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item>
<name></name>
</item>
</root>
But my requirement is such that I need to create a XML file whose output is:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item>
<name url = "C:\htdocs\proj1\source_file1"/>
<name url = "C:\htdocs\proj1\source_file2"/>
<name url = "C:\htdocs\proj1\source_file3"/>
</item>
</root>
I have tried in this fashion:
<?php
$domtree = new DOMDocument('1.0', 'UTF-8');
$domtree->formatOutput = true;
$xmlRoot = $domtree->createElement("root");
$xmlRoot = $domtree->appendChild($xmlRoot);
$item = $domtree->createElement("item");
$item = $xmlRoot->appendChild($item);
$name= $domtree->createElement("name");
$name = $item->appendChild($name);
$sav_xml = $domtree->saveXML();
$handle = fopen("new.xml", "w");
fwrite($handle, $sav_xml);
fclose($handle);
?>
But I wanted to append/add the url="path" to my elements. I have tried declaring variables with url and path but this throws me errors like:
Uncaught exception 'DOMException' with message 'Invalid Character Error'
Any ideas how to approach this problem!
Thanks
You just have to declare that attributes via php DOM:
...
$name= $domtree->createElement("name");
$urlAttribute = $domtree->createAttribute('url');
$urlAttribute->value = 'C:\htdocs\proj1\source_file1';
$name->appendChild($urlAttribute);
$item->appendChild($name);
...
Link to DOMDocument docs

Categories