I am looking for a way to convert a PHP file that I retrieve from a website into XML format using a PHP script.
The returned file I get is:
{ "days": [
{"reference":"13L6-A67-1", "dayinit":"4","hourinit":"9"},
{"reference":"13L6-A67-1", "dayinit":"5","hourinit":"9"} ]}
Is there anyway I could convert this to an XML file like this:
<?xml version="1.0"?>
<days>
<day>
<lesson>
<reference>13L6-A67-1</reference>
<hourinit>9</hourinit>
</lesson>
</day>
<day>
<lesson>
<reference>13L6-A67-1</reference>
<hourinit>9</hourinit>
</lesson>
</day>
</days>
Preferably so it groups data based on the "dayinit".
You can convert the data to an array and loop through it:
$test_array = json_decode('{ "days": [
{"reference":"13L6-A67-1", "dayinit":"4","hourinit":"9"},
{"reference":"13L6-A67-1", "dayinit":"5","hourinit":"9"} ]}',true);
$xml = '<?xml version="1.0"?>';
$xml .= '<days>';
foreach($test_array['days'] as $day) {
$xml .= '<day>';
$xml .= '<lesson>';
$xml .= '<reference>';
$xml .= $day['reference'];
$xml .= '</reference>';
$xml .= '<dayinit>';
$xml .= $day['reference'];
$xml .= '</reference>';
$xml .= '</dayinit>';
$xml .= $day['hourinit'];
$xml .= '</hourinit>';
$xml .= '</lesson>';
$xml .= '</day>';
}
$xml .= '</days>';
What you retrieve is content written in JSON. You could try to use PHP native functions to transform your content. The following example is rough draw how you could approach your solution.
First, fetch and decode JSON (documentation):
$json = '...'; // JSON content
$data = json_decode($json, true);
Then, use the XML Parser (documentation) to render your $data into XML:
// Something like
$xml_parser = xml_parser_create();
xml_parse($xml_parser, $data);
Related
I am developing a webservice using Nusoap to send xml data, and this time I have to send data with latin characters like 'ó'. However when I put it in the soap client it stops working. Below is a summary of code being develped to test sending xml with latin characters.
This is ths summary of server code being developed:
include_once("nusoap/nusoap.php");
$server = new soap_server();
$server->configureWSDL("PersonImport","urn:PersonImport");
$server->register("PersonImport",array("login" => "xsd:string", 'senha' => 'xsd:string', 'fornecedor' => 'xsd:string'),array("return" => "xsd:string"),"urn:PersonImport","urn:PersonImport#PersonImport");
function PersonImport($login,$senha,$fornecedor) {
//Just for debug purposes
$return = "My login Is <b>".$login . "</b> And My senha Is <b>".$senha."</b> And My fornecedor Is <b>".$fornecedor."</b>.";
(...)(ommited code, xml parsing and response xml generation)
return $return;
}
This is ths summary of client code:
<?php
require_once("nusoap/nusoap.php");
$client = new soapclient("example.com?wsdl");
$xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>";
$xml .= "<fornecedor>";
$xml .= "<NAME1>Gian</NAME1>";
$xml .= "<MCOD1>Giancarlo SA</MCOD1>";
$xml .= "<STCD1>80048303000113</STCD1>";
$xml .= "<STCD2>55670185501</STCD2>";
$xml .= "<STCD3>5508150087</STCD3>";
$xml .= "<RG>359730553</RG>";
$xml .= "<STRAS>rua itororó</STRAS>";
$xml .= "<HOUSE_NUM1>81</HOUSE_NUM1>";
$xml .= "<HOUSE_NUM2>301</HOUSE_NUM2>";
$xml .= "<ORT02>Menino Deus</ORT02>";
$xml .= "<PSTLZ>90110290</PSTLZ>";
$xml .= "<REGIO>RS</REGIO>";
$xml .= "<ORT01>Porto Alegre</ORT01>";
$xml .= "<TELF1>32335675</TELF1>";
$xml .= "<TELFX>32335675</TELFX>";
$xml .= "<SMTP_ADDR>teste#teste.com</SMTP_ADDR>";
$xml .= "<ERDAT>2016-10-04</ERDAT>";
$xml .= "<ChangeData>2016-10-04</ChangeData>";
$xml .= "<StartData>2016-10-04</StartData>";
$xml .= "<OffData>2016-10-04</OffData>";
$xml .= "</fornecedor>";
$result = $client->PersonImport("login","password", $xml);
echo $result;
The line
$xml .= "<STRAS>rua itororó</STRAS>";
has a special character. If I remove the 'ó' character it works.
I tried to set encoding on xml:
$xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>";
This worked for me when I had to parse xml with SimpleXML Parser, but it didn't work on soap.
I tried to set header of the page for utf8 or ISO-8859-1 like this:
header("Content-type:text/html; charset=UTF-8");
or:
header ('Content-type: text/html; charset=ISO-8859-1');
I tried to use htmlentities, but the entity for 'ó' is '& o a c u t e;' which has the special character '&' and then the same problem happens.
function serialize didn't resolve the problem.
I couldn't find an answer until now on google.
Is it possible to pass latin special characters using nusoap? There must be a way.
Looks like I found a way. Using CDATA I can escape the '&', so I can use htmlentities on strings, like this:
$xml .= "<STRAS><![CDATA[".htmlentities("Rua Itororó")."]]></STRAS>";
Im creating simple PHP code to generate sitemap.xml file, but the problem is, that the file is unformatted. If the file was smaller, I could look at it in browser, but it has about 1,5 MB and Chrome just gives up while loading it (IE loads it and you can view it, but its lagging really hard).
I googled and tried different solutions (even from this site), but none of them worked, so Im humbly asking for your help. Also Im using the newest PHP version and my server runs on Unix based OS if thats important.
Here is code Im using (there are couple thousands (15.000+) rows in the table, so XML file is pretty long:
$xml = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
$xml .= "<url>";
$xml .= "<loc>MY.URL.COM/</loc>";
$xml .= "<changefreq>always</changefreq>";
$xml .= "<priority>1.00</priority>";
$xml .= "</url>";
$xml .= "<url>";
$xml .= "<loc>MY.URL.COM/upload.php</loc>";
$xml .= "<changefreq>weekly</changefreq>";
$xml .= "<priority>0.80</priority>";
$xml .= "</url>";
$select = dbquery("SELECT * FROM MY TABLE");
while ($data = dbarray($select)) {
$xml .= "<url>";
$xml .= "<loc>MY.URL.COM/?id=".$data['id']."</loc>";
$xml .= "<changefreq>daily</changefreq>";
$xml .= "<priority>0.50</priority>";
$xml .= "</url>";
}
$xml .= '</urlset>';
$sxml = new SimpleXMLElement($xml);
$dom = new DOMDocument('1.0');
$dom->formatOutput = true;
$dom->loadXML($sxml->asXML());
$dom->saveXML("sitemap.xml");
Also, every time after new page is added Im running this code to append it to sitemap file and its appending it into one row, so need to fix that too.
Im trying both codes separately, so Im sure the first one doesnt format the document at all.
$sitemap = simplexml_load_file("sitemap.xml");
$url = $sitemap->addChild('url');
$url->addChild("loc", "MY.URL.COM/?id=".$get_id['id']);
$url->addChild("changefreq", "daily");
$url->addChild("priority", "0.50");
$sitemap->asXML("sitemap.xml");
By Unreadable I mean its saved in one line like this:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url><loc>MY.URL.COM?id=1</loc><changefreq>daily</changefreq><priority>0.50</priority></url><url><loc>MY.URL.COM?id=2</loc><changefreq>daily</changefreq><priority>0.50</priority></url><url><loc>MY.URL.COM?id=5</loc><changefreq>daily</changefreq><priority>0.50</priority></url><url><loc>MY.URL.COM?id=7</loc><changefreq>daily</changefreq><priority>0.50</priority></url></urlset>
Instead of:
<?xml version="1.0"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>MY.URL.COM?id=1</loc>
<changefreq>daily</changefreq>
<priority>0.50</priority>
</url>
<url>
<loc>MY.URL.COM?id=2</loc>
<changefreq>daily</changefreq>
<priority>0.50</priority>
</url>
<url>
<loc>MY.URL.COM?id=5</loc>
<changefreq>daily</changefreq>
<priority>0.50</priority>
</url>
<url>
<loc>MY.URL.COM?id=7</loc>
<changefreq>daily</changefreq>
<priority>0.50</priority>
</url>
</urlset>
**
WORKING CODE:
**
$xml = "<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd'>";
$select = dbquery("SELECT * FROM MY TABLE");
while ($data = dbarray($select)) {
$xml .= "<url>";
$xml .= "<loc>MY.URL.COM/?id=".$data['id']."</loc>";
$xml .= "<changefreq>daily</changefreq>";
$xml .= "<priority>0.50</priority>";
}
$xml .= '</urlset>';
$sitemap = simplexml_load_file($xml);
$sxe = new SimpleXMLElement($xml);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml);
$dom->save("sitemap.xml");
Code to append to existing xml file:
$sitemap = simplexml_load_file("sitemap.xml");
$url = $sitemap->addChild('url');
$url->addChild("loc", "MY.URL.COM/?id=".$get_id['id']);
$url->addChild("changefreq", "daily");
$url->addChild("priority", "0.50");
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($sitemap->asXML());
$dom->save('sitemap.xml');
Edit Start
//you don't need simplexml
// $sxml = new SimpleXMLElement($xml);
$dom = new DOMDocument('1.0');
$dom->formatOutput = true;
$dom->loadXML($xml); // can use the xml string
$dom->save("sitemap.xml"); // need to use save() rather than saveXML
Edit End
The code that you have written for the first time will do a proper formatting. Problem will arise when you add a new element/node to sitemap.xml using simplexml.
If you want a properly formatted XML, you will need to save it using DOMDocument every time, the same one that you are doing initially.
What you are doing
$sitemap = simplexml_load_file("sitemap.xml");
$url = $sitemap->addChild('url');
$url->addChild("loc", "MY.URL.COM/?id=".$get_id['id']);
$url->addChild("changefreq", "daily");
$url->addChild("priority", "0.50");
$sitemap->asXML("sitemap.xml");
Try changing it to this:
$sitemap = simplexml_load_file("sitemap.xml");
$url = $sitemap->addChild('url');
$url->addChild("loc", "MY.URL.COM/?id=".$get_id['id']);
$url->addChild("changefreq", "daily");
$url->addChild("priority", "0.50");
$dom = new DOMDocument('1.0',LIBXML_NOBLANKS);
$dom->formatOutput = true;
$dom->loadXML($sitemap->asXML());
$dom->saveXML('sitemap.xml');
Hope it helps.
One other thing to look at is if server where your code is running is Unix/Linux it'll use Unix end of lines (LF) which if viewed with Windows editors or browser may not show right as they expect (CR-LF).
Would anyone know how i can "explode" a string back into "normal" xml format?
I found this script (ref:gooseflight,2010) that looks like it can do the job but the output comes out stuck together.
Here's the code:
enter code herefunction combineXML($file)
{
global $xmlstr;
$xml = simplexml_load_file($file);
foreach($xml as $element)
$xmlstr .= $element->asXML();
}
$files[] = "tmp.xml";
$files[] = "traduction.xml";
$xmlstr = '<CAB>';
foreach ($files as $file)
combineXML($file);
$xmlstr .= '</CAB>';
// Convert string to XML for further processing
$xml = simplexml_load_string($xmlstr);
$bytes = file_put_contents("combined.xml", $xml->asXML())
Here is the output:
<?xml version="1.0" encoding="UTF-8"?>
<CAB>
<CABO>XXXXXXXXXX0987650003</CABO><ACTIVITY>NONE</ACTIVITY><BEORI>blablaE</BEORI>BEDEST>blabla</BEDEST><NATRELA>more blabla</NATRELA><ANE>2014</ANE><NODEP>1111</NODEP>
</CAB>
So how could i seperate the nodes to look like this?:
<?xml version="1.0" encoding="UTF-8"?>
<CAB>
<CABO>XXXXXXXXXX0987650003</CABO>
<ACTIVITY>NONE</ACTIVITY>
<BEORI>blablaE</BEORI>
<BEDEST>blabla</BEDEST>
<NATRELA>more blabla</NATRELA>
<ANE>2014</ANE>
<NODEP>1111</NODEP>
.....
</CAB>
Would anyone know how to fix it?
I would suggest to use DomDocument class to save the XML; check this:
$dom_obj = new DOMDocument();
$dom_obj->loadXML($file);
// Do all your changes to the file by using DomDocument command (e.g. CreateElement, CreateAttribute, etc)
$dom_obj->formatOutput = true;
$dom_obj->save($file);
I am using an API however the way that they setup their returned XML is incorrect so I am needing to come up with a solution for parsing it. i am unable to convert to JSON (my preferred return method) because they don't support it. Below I have listed my XML and PHP.
XML Returned by API
<?xml version="1.0" encoding="utf-8"?>
<interface-response>
<Domain>example.com</Domain>
<Code>211</Code>
<Domain>example.net</Domain>
<Code>210</Code>
<Domain>example.org</Domain>
<Code>211</Code>
</interface-response>
Each Code is for the previous domain. I have no idea how to tie these two together and still be able to loop through all of the results returned. There will essentially be one Domain and one Code returned for each Top Level Domain, so a lot of results.
PHP code so far:
<?php
$xml = new SimpleXMLElement($data);
$html .= '<table>';
foreach($xml->children() as $children){
$html .= '<tr>';
$html .= '<td>'.$xml->Domain.'</td>';
if($xml->Code == 211){
$html .= '<td>This domain is not avaliable.</td>';
}elseif($xml->Code == 210){
$html .= '<td>This domain is avaliable.</td>';
}else{
$html .= '<td>I have no idea.</td>';
}
$html .= '<tr>';
}
$html .= '</table>';
echo $html;
?>
If you don't want to deal with crappy XML (I'm not saying XML is crappy in general, but this one is) you could consider something like this:
<?php
$responses = [];
$responses['210'] = 'This domain is avaliable.';
$responses['211'] = 'This domain is not avaliable.';
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<interface-response>
<Domain>example.com</Domain>
<Code>211</Code>
<Domain>example.net</Domain>
<Code>210</Code>
<Domain>example.org</Domain>
<Code>211</Code>
</interface-response>
XML;
$data = (array) simplexml_load_string($xml);
$c = count($data['Domain']);
for($i = 0; $i < $c; $i++)
{
echo $data['Domain'][$i], PHP_EOL;
echo array_key_exists($data['Code'][$i], $responses) ? $responses[$data['Code'][$i]] : 'I have no idea', PHP_EOL;
}
Output
example.com
This domain is not avaliable.
example.net
This domain is avaliable.
example.org
This domain is not avaliable.
I would like to create a new simplified xml based on an existing one:
(using "simpleXml")
<?xml version="1.0" encoding="UTF-8"?>
<xls:XLS>
<xls:RouteInstructionsList>
<xls:RouteInstruction>
<xls:Instruction>Start</xls:Instruction>
</xls:RouteInstruction>
</xls:RouteInstructionsList>
<xls:RouteInstructionsList>
<xls:RouteInstruction>
<xls:Instruction>End</xls:Instruction>
</xls:RouteInstruction>
</xls:RouteInstructionsList>
</xls:XLS>
Because there are always colons in the element-tags, it will mess with "simpleXml", I tried to use the following solution->link.
How can I create a new xml with this structure:
<main>
<instruction>Start</instruction>
<instruction>End</instruction>
</main>
the "instruction-element" gets its content from the former "xls:Instruction-element".
Here is the updated code:
But unfortunately it never loops through:
$source = "route.xml";
$xmlstr = file_get_contents($source);
$xml = #simplexml_load_string($xmlstr);
$new_xml = simplexml_load_string('<main/>');
foreach($xml->children() as $child){
print_r("xml_has_childs");
$new_xml->addChild('instruction', $child->RouteInstruction->Instruction);
}
echo $new_xml->asXML();
there is no error-message, if I leave the "#"…
/* the use of # is to suppress warning */
$xml = #simplexml_load_string($YOUR_RSS_XML);
$new_xml = simplexml_load_string('<main/>');
foreach ($xml->children() as $child)
{
$new_xml->addChild('instruction', $child->RouteInstruction->Instruction);
}
/* to print */
echo $new_xml->asXML();
You could use xpath to simplify things. Without knowing the full details, I don't know if it will work in all cases:
$source = "route.xml";
$xmlstr = file_get_contents($source);
$xml = #simplexml_load_string($xmlstr);
$new_xml = simplexml_load_string('<main/>');
foreach ($xml->xpath('//Instruction') as $instr) {
$new_xml->addChild('instruction', (string) $instr);
}
echo $new_xml->asXML();
Output:
<?xml version="1.0"?>
<main><instruction>Start</instruction><instruction>End</instruction></main>
Edit: The file at http://www.gps.alaingroeneweg.com/route.xml is not the same as the XML you have in your question. You need to use a namespace like:
$xml = #simplexml_load_string(file_get_contents('http://www.gps.alaingroeneweg.com/route.xml'));
$xml->registerXPathNamespace('xls', 'http://www.opengis.net/xls'); // probably not needed
$new_xml = simplexml_load_string('<main/>');
foreach ($xml->xpath('//xls:Instruction') as $instr) {
$new_xml->addChild('instruction', (string) $instr);
}
echo $new_xml->asXML();
Output:
<?xml version="1.0"?>
<main><instruction>Start (Southeast) auf Sihlquai</instruction><instruction>Fahre rechts</instruction><instruction>Fahre halb links - Ziel erreicht!</instruction></main>