Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

php - converting xml to json does not work when there is CDATA

Tags:

json

php

xml

If I use the following php code to convert an xml to json:

<?php

header("Content-Type:text/json");

$resultXML = "
<QUERY>
   <Company>fcsf</Company>
   <Details>
      fgrtgrthtyfgvb
   </Details>
</QUERY>
";

$sxml = simplexml_load_string($resultXML);
echo  json_encode($sxml);
?>

I get

{"Company":"fcsf","Details":"\n      fgrtgrthtyfgvb\n   "}

However, If I use CDATA in the Details element as follows:

<?php

header("Content-Type:text/json");

$resultXML = "
<QUERY>
   <Company>fcsf</Company>
   <Details><![CDATA[
      fgrtgrthtyfgvb]]>
   </Details>
</QUERY>
";

$sxml = simplexml_load_string($resultXML);
echo  json_encode($sxml);

?>

I get the following

{"Company":"fcsf","Details":{}}

In this case the Details element is blank. Any idea why Details is blank and how to correct this?

like image 552
Ketan Avatar asked Feb 04 '14 09:02

Ketan


1 Answers

This is not a problem with the JSON encoding – var_dump($sxml->Details) shows you that SimpleXML already messed it up before, as you will only get

object(SimpleXMLElement)#2 (0) {
}

– an “empty” SimpleXMLElement, the CDATA content is already missing there.

And after we figured that out, googling for “simplexml cdata” leads us straight to the first user comment on the manual page on SimpleXML Functions, that has the solution:

If you are having trouble accessing CDATA in your simplexml document, you don't need to str_replace/preg_replace the CDATA out before loading it with simplexml.

You can do this instead, and all your CDATA contents will be merged into the element contents as strings.

$xml = simplexml_load_file($xmlfile, 'SimpleXMLElement', LIBXML_NOCDATA);

So, use

$sxml = simplexml_load_string($resultXML, 'SimpleXMLElement', LIBXML_NOCDATA);

in your code, and you’ll get

{"Company":"fcsf","Details":"\n      fgrtgrthtyfgvb\n   "}

after JSON-encoding it.

like image 156
CBroe Avatar answered Nov 15 '22 23:11

CBroe