compared with
Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (25)

View Page History
0.2 - 30 May 2007: Revised proposal after incorporating the review comments.
0.3 - 31 May 2007: Another revision done to do the logic in two functions.
0.4 - 14 June 2007: Minor changes made before the first commit into incubator.
{zone-data}

In order to bring the xml2json conversion feature to the Zend Framework, we will add two new static functions to the Zend_Json class in Json.php file. Those functions are described below.

* fromXML fromXml
* _processXML _processXml

A function named "fromXML" "fromXml" is the one that users will call to convert any arbitrary XML content to JSON data. This function will take as input, a string containing XML formatted content and an optional boolean value of true to indicate the need to ignore or false for NOT to ignore the XML attributes in the conversion process. This function will then convert this input XML string value into SimpleXMLElement. Then, it will call another worker function (_processXML) (_processXml) in the same class to convert the XML elements into a PHP associative array. Once the PHP array is created, it simply uses the Zend_Json "encode" function to convert that PHP array into a JSON formatted string. Result from this conversion will be returned to the caller. In the case of any input error, this function will throw a Zend_Json_Exception.

A worker function named "_processXML" "_processXml" will provide a recursive logic to do the conversion of an XML tree into a PHP associative array. This function takes three parameters. First parameter is the SimpleXMLElement object that contains an XML fragment to be converted into a PHP array. The second parameter is a boolean value that determines if XML attributes need to be preserved in the conversion process. By default, this function will ignore the XML attributes i.e. it will not do anything with the XML attributes during the conversion process. The third parameter specifies the current recursion depth which is used by the internal logic in this function. It recursively traverses the nested XML content structure and stores the visited XML contents into a PHP associative array structure. At the end of the XML tree traversal, it returns the PHP array with all the element/value pairs that were present in the XML input content. If needed, this function will also optionally store the XML attributes in the PHP array so that it can be preserved in the final JSON data. In case of a recursion runtime error, this function will throw a Zend_Json_Exception.

In addition to the above, this conversion logic will also require the following in the Zend_Json class.
{zone-data:milestones}
* Milestone 1: \[DONE\] Publish this proposal.
* Milestone 2: \[DONE\] Revise proposal, approve for Incubator development.
* Milestone 3: Commit working prototype to Incubator.
* Milestone 4: Commit unit tests and documentation.

{zone-data:use-cases}
The use cases below show a few scenarios that explain the input and output characteristics of Zend_xml2json function. feature.

||UC-01||
As you can see from the JSON formatted output shown above, the conversion logic preserved the entire text (PHP script in this case) that was part of the CDATA section in the input XML. It is also interesting to note that the entire CDATA section content is converted into a single string. Some of the special characters are automatically escaped by preceding such characters with a backslash character. This powerful feature to handle CDATA sections is built into the xml2json conversion logic.

All five use cases combined together demonstrate the potential use of the xml2json conversion function named fromXML. fromXml. Even though this function looks deceptively simple, the benefit it will deliver to the PHP user community could be very valuable.

{zone-data}

{code}
/**
* fromXML fromXml - Converts XML to JSON
*
* Converts a XML formatted string into a JSON formatted string.
* @throws Zend_Json_Exception
*/
public static function fromXML fromXml ($xmlStringContents, $ignoreXmlAttributes=true) {
// Load the XML formatted string into a Simple XML Element object.
$simpleXmlElementObject = simplexml_load_string($xmlStringContents);
// If it is not a valid XML content, throw an exception.
if ($simpleXmlElementObject == null) {
throw new Zend_Json_Exception('Function fromXML fromXml was called with an invalid XML formatted string.');
} // End of if ($simpleXmlElementObject == null)


// Call the recursive function to convert the XML into a PHP array.
$resultArray = self::_processXML($simpleXmlElementObject, self::_processXml($simpleXmlElementObject, $ignoreXmlAttributes);

// Convert the PHP array to JSON using Zend_Json encode method.
$jsonStringOutput = self::encode($resultArray);
return($jsonStringOutput);
} // End of function fromXML. fromXml.
{code}

The second function is a static function that provides protected access to the callers. Only the front-end function "fromXML" "fromXml" discussed above needs access to the logic inside this protected function. The xml2json conversion logic is a recursive one. This static function with added comments is shown below.

{code}
/**
* _processXML _processXml - Contains the logic for xml2json
*
* The logic in this function is a recursive one.
*
* The main caller of this function (i.e. fromXML) fromXml) needs to provide
* only the first two parameters i.e. the SimpleXMLElement object and
* the flag for ignoring or not ignoring XML attributes. The third parameter
* @throws Zend_Json_Exception
*/
protected static function _processXML _processXml ($simpleXmlElementObject, $ignoreXmlAttributes, $recursionDepth=0) {
// Keep an eye on how deeply we are involved in recursion.
if ($recursionDepth > self::$maxRecursionDepthAllowed) {
// XML tree is too deep. Exit now by throwing an exception.
throw new Zend_Json_Exception(
"Function _processXML _processXml exceeded the allowed recursion depth of " .
self::$maxRecursionDepthAllowed);
} // End of if ($recursionDepth > self::$maxRecursionDepthAllowed)
// Increase the recursion depth by one.
$recursionDepth++;
$resultArray[$key] = self::_processXML self::_processXml ($value, $ignoreXmlAttributes, $recursionDepth);

// Decrease the recursion depth by one.
return (trim(strval($simpleXmlElementObject)));
} // End of if (is_array($simpleXmlElementObject))
} // End of function _processXML. _processXml.
{code}

* A value of 1 means ignore XML attributes and a 0 means not to ignore XML attribtes.
* If the optional second argument is omitted, then the XML attributes will be ignored.
* It uses the fromXML fromXml function in the Zend_Json class to convert the XML string into a JSON string.
*
* @category Zend
$jsonContents = "";
// Convert it to JSON now.
// fromXML fromXml function simply takes a String containing XML contents as input.
$jsonContents = Zend_Json::fromXML($xmlStringContents, Zend_Json::fromXml($xmlStringContents, $ignoreXmlAttributes);

echo("JSON formatted output generated by Zend_Json::fromXML\n\n"); Zend_Json::fromXml\n\n");
echo($jsonContents);
?>