XML to JSON with PHP

7 09 2010

In a previous post, Buzz Words, I used PHP to JSON-encode some XML contained within a couple of SimpleXML elements. In this post, we are going to delve more deeply into this issue of converting XML to JSON.

There are a few ways we can do the JSON encoding, one involves using PHP’s json_encode(), which is part of the JSON extension that is included in PHP 5.2 and higher versions. Before making its way into PHP’s core, the extension was a PECL library developed for PHP4 — see http://pecl.php.net/package/json.

We can alternatively use a component of the Zend Framework, Zend_Json. If all you want to do is simply json encoding, then you really don’t need to use Zend_Json as http://thecodecentral.com/2007/09/13/easy-json-encodingdecoding-in-php#header-1 rightfully notes.

In this particular case we’re going to convert $xml which contains the following xml string:

$xml = '<?xml version="1.0" encoding="UTF-8"?>
<contacts>
    <contact id="1">
        <name>Tom Jones</name>
        <phone>111-222-3344</phone>
        <address>123 MyStreet, MyCity, MyState, 12345-1122</address>
    </contact>
   <contact id="2">
        <name>Mary Smith</name>
        <phone>112-223-3346</phone>
        <address>125 MyAvenue, MyCity, MyState, 12345-1123</address>
    </contact>
</contacts>';

using PHP’s json_encode() as follows:

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

which produces the following JSON:

{"contact":
          [
             {"@attributes":{"id":"1"},
                "name":"Tom Jones",
                "phone":"111-222-3344",
                "address":"123 MyStreet, MyCity, MyState, 12345-1122"
             },
            {"@attributes":{"id":"2"},
               "name":"Mary Smith",
               "phone":"112-223-3346",
               "address":"125 MyAvenue, MyCity, MyState, 12345-1123"}
          ]
}

Note, that even the XML attribute properties were included in the results.

I also achieved similar results using the Zend Framework’s Zend_Json component on my Windows box using Wampserver, as follows:

$path = realpath("/wamp/www/ZendFramework/library");
set_include_path($path);
require_once 'Zend/Json.php';
echo Zend_Json::encode($sxml);

The component can come in handy especially if for some reason PHP’s json_encode() is unavailable to you. (See note at http://us3.php.net/manual/en/json.requirements.php.)  Fortunately, the Zend_Json component is able to function in two modes (see http://framework.zend.com/manual/en/zend.json.advanced.html). It has an internal coder/decoder such that if you have json_encode() in your PHP installation, it will use that. Otherwise, the framework has its own implementation in PHP of that function which will run albeit much slower. For more info see http://framework.zend.com/manual/en/zend.json.advanced.html. There is one advantage to using this second mode — it will also give you any class name information. So, for example, when I ran the following code:

$path = realpath("/wamp/www/ZendFramework/library");
set_include_path($path);

require_once 'Zend/Json.php';
Zend_Json::$useBuiltinEncoderDecoder = true;
echo Zend_Json::encode($sxml);

the results included the class name of $sxml, as follows:

{"__className":"SimpleXMLElement","contact":[{"__className":"SimpleXMLElement","@attributes":{"id":"1"},"name":"Tom Jones","phone":"111-222-3344","address":"123 MyStreet, MyCity, MyState, 12345-1122"},{"__className":"SimpleXMLElement","@attributes":{"id":"2"},"name":"Mary Smith","phone":"112-223-3346","address":"125 MyAvenue, MyCity, MyState, 12345-1123"}]}

There is also a PEAR library for PHP4 to handle JSON encoding — see http://pear.php.net/package/Services_JSON. The PEAR library is referenced in the article http://www.ibm.com/developerworks/xml/library/x-xml2jsonphp/ and that article led to the development of Zend_Json::fromXML() — see http://framework.zend.com/manual/en/zend.json.xml2json.html. What’s nice about using the Zend_Json static method fromXml() is that by using it you get a much more complete result, as follows:

$jsonContents = Zend_Json::fromXml($xml, false);
var_dump($jsonContents);

You can control whether fromXml() ignores the attribute properties by setting its second parameter to true or includes them by passing in false. In this case, the results are as follows:

{"contacts":{"contact":[{"@attributes":{"id":"1"},"name":"Tom Jones","phone":"111-222-3344","address":"123 MyStreet, MyCity, MyState, 12345-1122"},{"@attributes":{"id":"2"},"name":"Mary Smith","phone":"112-223-3346","address":"125 MyAvenue, MyCity, MyState, 12345-1123"}]}}

With this last result, if we wanted to modify Mary Smith’s phone number, we could do so and then convert the data back to XML whereas with the previous two results that would be difficult since we are missing the root element “contacts.” For more information about this method, see http://framework.zend.com/manual/en/zend.json.xml2json.html

Of course, once you get the JSON encoded string, you want to be able to do something useful with it. Since JSON is a subset of JavaScript (see http://www.json.org/), let’s display the information in $json which resulted from using the PHP json_encode().

I demonstrate how to do this with JavaScript using the following PHP file:

<html>
<title>Using JSON in JS</title>
<body>
<h1>Data</h1>
<div id="res">
</div>
<script>
var data = <?php  echo $json; ?>;
var i = 0;
var str='';
var obj = data.contact;
for (i in obj) {
    str += obj[i]["@attributes"].id + ' ' + obj[i].name + ", " + obj[i].phone + ", " + obj[i].address + '
';
}
document.getElementById('res').innerHTML = str;
</script>
</body>
</html>

In the above script, var data is assigned a JavaScript object that consists of an array of objects. For comfortable handling, var obj is assigned data.contact, an array of objects for each contact. The for(i in obj) is the JavaScript equivalent of PHP’s foreach loop.

JSON is typically used for AJAX apps, so let’s set things up accordingly and use jQuery for the front-end processing, as follows:
script1.php

<?php
$xml = '
<contacts>
    <contact id="1">
        <name>Tom Jones</name>
        <phone>111-222-3344</phone>
        <address>123 MyStreet, MyCity, MyState, 12345-1122</address>
    </contact>
   <contact id="2">
        <name>Mary Smith</name>
        <phone>112-223-3346</phone>
        <address>125 MyAvenue, MyCity, MyState, 12345-1123</address>
    </contact>
</contacts>';

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

Note how I use SimpleXML to load the string of XML to produce a SimpleXML element. I pass that object to json_encode and the result is JSON which will be transported back to JavaScript in this AJAX application.

script2.html

<html>
<head><title>Using JSON with jQuery</title>
</head>
<body>
<h1>Data</h1>
<div id="res">
</div>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
$.getJSON('./script1.php', function(data) {
  $.each(data.contact, function(index) {
  		$('#res').append('<p>'
		+ data.contact[index]["@attributes"].id + " "
		+ data.contact[index].name + ", "
		+ data.contact[index].phone + ", "
		+ data.contact[index].address + '</p>');
  });
});
</script>
</body>
</html>

Using  $.getJSON() is an AJAX shortcut to get the the JSON produced by the previous script. The JSON will be parsed into an array of objects. When the results are made available to JavaScript , then they can be used immediately. We iterate through each contact, extracting attribute, name and contact information which we then display in the DIV element res. What we don’t see is that the actual parsing of the JSON is done by $.parseJSON(). For more info see http://api.jquery.com/jQuery.getJSON/.

This work is licensed under a Creative Commons License
.

Advertisements

Actions

Information

10 responses

28 01 2011
nick

Please fix your xml code above.

It needs the opening bracket and question mark for xml…
<?xml

28 01 2011
Sharon Lee Levy

Nick,

Thank you pointing out the typo which is now corrected.

— Sharon

13 02 2011
» links for 2011-02-13 Thej Live

[…] XML to JSON with PHP « Sharon Lee Levy's Blog (tags: json wordpress)   […]

28 05 2011
Benson

Thanks for the post Sharon, helped me out alot

29 05 2011
Sharon Lee Levy

Benson,

You’re welcome — glad you found the post helpful.

Regards,
Sharon

1 09 2011
Oliver Lillie (@buggedcom)

Would like to just quickly point out that if you have xml like so

<contacts>
<contact id=”1″>Tom Jones</contact>
<contact id=”2″>Mary Smith</contact>
</contacts>’;

The attributes on the contact do not get properly carried over to the json.

1 09 2011
Sharon Lee Levy

Oliver,

Thanks for your comment. In order to carry over the attributes, so that they appear in the resulting JSON, you could do something like the following:

$xml = '<contacts>
<contact id="1">Tom Jones</contact>
<contact id="2">Mary Smith</contact>
</contacts>';

$sxml = simplexml_load_string($xml );
$encoded = null;
foreach ($sxml->contact as $o) {
  $encoded[] = json_encode( $o );
}

var_dump($encoded);

There’s a note at php.net that relates to this issue. See note of bojan 04-Feb-2008 12:38 at http://php.net/manual/en/function.simplexml-load-string.php.

Alternately, you could also achieve similar results as follows:

$xml = '<contacts>
<contact id="1">Tommy Jones</contact>
<contact id="2">Maryianne Smith</contact>
</contacts>';

$dom = new DOMDocument;
$dom->loadXML( $xml );
if (!$dom) {
    echo 'Error while parsing the document';
    exit;
}

$s = simplexml_import_dom($dom);
foreach( $s->contact as $c)
{
   print_r( json_encode($c) );
}   
5 03 2012
Stefan

Thanks for sharing. Despite being two years old, this article is still relevant and helped me out.

15 10 2012
PHP Convert XML to JSON « tediscript.wordpress.com

[…] https://slevy1.wordpress.com/2010/09/07/xml-to-json-with-php/ Share this:TwitterFacebookLike this:LikeBe the first to like this.   […]

10 07 2013
SimpleXML and JSON Encode in PHP – Part I | hakre on wordpress

[…] Under normal circumstances this is pretty straight forward, this is similar to what a previous post XML to JSON with PHP by Sharon Lee (Sep 2010) or another one Simple XML to JSON with PHP by Sean Biefeld (Oct 2011) […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: