Project

General

Profile

Download (7.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * This PHP class converts XML-based data into JSON formatted data.
5
 *
6
 * This program makes use of several open source PHP utility classes and
7
 * functions.
8
 *
9
 * First Created on: Oct/04/2006
10
 * Last Modified on: Oct/07/2006 (updated to Drupal coding standard Oct 19/2012)
11
 *
12
 * @licence
13
 *   This code is made available free of charge with the rights to use, copy,
14
 *   modify, merge, publish and distribute. This Software shall be used for
15
 *   Good, not Evil.
16
 */
17

    
18
module_load_include('php', 'cdm_api', 'json/JSON');
19

    
20
// Internal program-specific Debug option.
21
define("DEBUG", FALSE);
22

    
23
// Maximum Recursion Depth that we can allow.
24
define("MAX_RECURSION_DEPTH_ALLOWED", 25);
25

    
26
// An empty string.
27
define("EMPTY_STR", "");
28

    
29
// SimpleXMLElement object property name for attributes.
30
define("SIMPLE_XML_ELEMENT_OBJECT_PROPERTY_FOR_ATTRIBUTES", "@attributes");
31

    
32
// SimpleXMLElement object name.
33
define("SIMPLE_XML_ELEMENT_PHP_CLASS", "SimpleXMLElement");
34

    
35
class xml2json {
36

    
37
  /**
38
   * Transforms the XML based String data into JSON format.
39
   *
40
   * If the input XML string is in table format, the resulting JSON output
41
   * will also be in table format. Conversely, if the input XML string is
42
   * in tree format, the resulting JSON output will also be in tree format.
43
   *
44
   * @param string $xmlStringContents
45
   *   XML data string.
46
   *
47
   * @return mixed
48
   *   JSON.
49
   */
50
  public static function transformXmlStringToJson($xmlStringContents) {
51
    /*
52
     Get the SimpleXMLElement representation of the function input
53
     parameter that contains XML string. Convert the XML string
54
     contents to SimpleXMLElement type. SimpleXMLElement type is
55
     nothing but an object that can be processed with normal property
56
     selectors and (associative) array iterators.
57
     simplexml_load_string returns a SimpleXMLElement object which
58
     contains an instance variable which itself is an associative array of
59
     several SimpleXMLElement objects.
60
     */
61
    $simpleXmlElementObject = simplexml_load_string($xmlStringContents);
62

    
63
    if ($simpleXmlElementObject == NULL) {
64
      return(EMPTY_STR);
65
    }
66

    
67
    $simpleXmlRootElementName = $simpleXmlElementObject->getName();
68

    
69
    if (DEBUG) {
70
      // Uncomment to see the inner details of
71
      // the SimpleXMLElement object.
72
      // var_dump($simpleXmlRootElementName);
73
      // var_dump($simpleXmlElementObject);
74
    }
75

    
76
    $jsonOutput = EMPTY_STR;
77
    // Let us convert the XML structure into PHP array structure.
78
    $array1 = xml2json::convertSimpleXmlElementObjectIntoArray($simpleXmlElementObject);
79

    
80
    if (($array1 != NULL) && (sizeof($array1) > 0)) {
81
      // Create a new instance of Services_JSON.
82
      $json = new Services_JSON();
83
      $jsonOutput = $json->encode($array1);
84

    
85
      if (DEBUG) {
86
        // var_dump($array1);
87
        // var_dump($jsonOutput);
88
      }
89
    }
90
    /* End of if (($array1 != NULL) && (sizeof($array1) > 0)). */
91

    
92
    return($jsonOutput);
93
  }
94
  /* End of function transformXmlStringToJson. */
95

    
96
  /**
97
   * Converts a SimpleXmlElementObject into an associative array.
98
   *
99
   * This function accepts a SimpleXmlElementObject as a single argument.
100
   * If the input XML is in table format (i.e. non-nested), the resulting
101
   * associative array will also be in a table format. Conversely, if the input
102
   * XML is in tree (i.e. nested) format, this function will return an
103
   * associative array (tree/nested) representation of that XML.
104
   *
105
   * There are so many ways to turn an XML document into a PHP array. Out of all
106
   * those options, the recursive logic here uses a method that is very nicely
107
   * documented by the PHP open source community in the SimpleXMLElement section
108
   * of the PHP manual available at www.php.net. Credit goes to all those kind
109
   * PHP (People Helping People!!!) souls.
110
   *
111
   * Caution and Remarks: IT IS A RECURSIVE FUNCTION.
112
   *
113
   * @param mixed $simpleXmlElementObject
114
   *   Simple XML Element Object.
115
   * @param int $recursionDepth
116
   *   Needs to be used only when this function is called recursively. It can
117
   *   be omitted when this function is called from another function.
118
   *
119
   * @return array
120
   *   If everything is successful, it returns an associate array containing
121
   *   the data collected from the XML format. Otherwise, it returns NULL.
122
   */
123
  public static function convertSimpleXmlElementObjectIntoArray($simpleXmlElementObject, &$recursionDepth = 0) {
124
    // Keep an eye on how deeply we are involved in recursion.
125
    if ($recursionDepth > MAX_RECURSION_DEPTH_ALLOWED) {
126
      // Fatal error. Exit now.
127
      return(NULL);
128
    }
129

    
130
    if ($recursionDepth == 0) {
131
      if (get_class($simpleXmlElementObject) != SIMPLE_XML_ELEMENT_PHP_CLASS) {
132
        // If the external caller doesn't call this function initially
133
        // with a SimpleXMLElement object, return now.
134
        return(NULL);
135
      }
136
      else {
137
        // Store the original SimpleXmlElementObject sent by the caller.
138
        // We will need it at the very end when we return from here for good.
139
        $callerProvidedSimpleXmlElementObject = $simpleXmlElementObject;
140
      }
141
    }
142
    /* End of if ($recursionDepth == 0) { */
143

    
144
    if (get_class($simpleXmlElementObject) == SIMPLE_XML_ELEMENT_PHP_CLASS) {
145

    
146
      // Get a copy of the simpleXmlElementObject.
147
      $copyOfsimpleXmlElementObject = $simpleXmlElementObject;
148

    
149
      // Get the object variables in the SimpleXmlElement object for us
150
      // to iterate.
151
      $simpleXmlElementObject = get_object_vars($simpleXmlElementObject);
152
    }
153

    
154
    // It needs to be an array of object variables.
155
    if (is_array($simpleXmlElementObject)) {
156

    
157
      // Initialize the result array.
158
      $resultArray = array();
159

    
160
      // Is the input array size 0? Then, we reached the rare CDATA text if any.
161
      if (count($simpleXmlElementObject) <= 0) {
162

    
163
        // Let us return the lonely CDATA. It could even be whitespaces.
164
        return (trim(strval($copyOfsimpleXmlElementObject)));
165
      }
166

    
167
      // Let us walk through the child elements now.
168
      foreach ($simpleXmlElementObject as $key => $value) {
169
        // When this block of code is commented, XML attributes will be
170
        // added to the result array.
171
        // Uncomment the following block of code if XML attributes are
172
        // NOT required to be returned as part of the result array.
173
        /*
174
         if((is_string($key)) && ($key == SIMPLE_XML_ELEMENT_OBJECT_PROPERTY_FOR_ATTRIBUTES)) {
175
         continue;
176
         }
177
         */
178
        // Let us recursively process the current element we just visited.
179
        // Increase the recursion depth by one.
180
        $recursionDepth++;
181
        $resultArray[$key] = xml2json::convertSimpleXmlElementObjectIntoArray($value, $recursionDepth);
182

    
183
        // Decrease the recursion depth by one.
184
        $recursionDepth--;
185
      }
186
      /* End of foreach($simpleXmlElementObject as $key=>$value) { */
187

    
188
      if ($recursionDepth == 0) {
189
        // That is it. We are heading to the exit now.
190
        // Set the XML root element name as the root [top-level] key of
191
        // the associative array that we are going to return to the caller of
192
        // this recursive function.
193
        $tempArray = $resultArray;
194
        $resultArray = array();
195
        $resultArray[$callerProvidedSimpleXmlElementObject->getName()] = $tempArray;
196
      }
197

    
198
      return ($resultArray);
199
    }
200
    else {
201
      // We are now looking at either the XML attribute text or
202
      // the text between the XML tags.
203
      return (trim(strval($simpleXmlElementObject)));
204
    }
205
    /* End of else. */
206

    
207
  }
208
  /* End of function convertSimpleXmlElementObjectIntoArray. */
209

    
210
}
211
/* End of class xml2json. */
(9-9/9)