1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Koch Framework |
5
|
|
|
* Jens-André Koch © 2005 - onwards. |
6
|
|
|
* |
7
|
|
|
* This file is part of "Koch Framework". |
8
|
|
|
* |
9
|
|
|
* License: GNU/GPL v2 or any later version, see LICENSE file. |
10
|
|
|
* |
11
|
|
|
* This program is free software; you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU General Public License as published by |
13
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
14
|
|
|
* (at your option) any later version. |
15
|
|
|
* |
16
|
|
|
* This program is distributed in the hope that it will be useful, |
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19
|
|
|
* GNU General Public License for more details. |
20
|
|
|
* |
21
|
|
|
* You should have received a copy of the GNU General Public License |
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
namespace Koch\Datatype; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Koch Framework - Class for handling and converting XML data. |
29
|
|
|
* |
30
|
|
|
* This class converts XML-based data into JSON or Array formatted data. |
31
|
|
|
*/ |
32
|
|
|
class XML |
|
|
|
|
33
|
|
|
{ |
34
|
|
|
const MAX_RECURSION_DEPTH_ALLOWED = 25; |
35
|
|
|
const FETCH_ATTRIBUTES = true; |
36
|
|
|
const REMOVE_ATTRIBUTES_SUBLEVEL = true; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* toJson. |
40
|
|
|
* |
41
|
|
|
* This function transforms the XML based String data into JSON format. If the input XML |
42
|
|
|
* string is in table format, the resulting JSON output will also be in table format. |
43
|
|
|
* Conversely, if the input XML string is in tree format, the resulting JSON output will |
44
|
|
|
* also be in tree format. |
45
|
|
|
* |
46
|
|
|
* @param string XML data string. |
47
|
|
|
* |
48
|
|
|
* @return false|string a string containing JSON table/tree formatted data. Otherwise, it returns an empty string. |
49
|
|
|
*/ |
50
|
|
|
public static function toJson($xml) |
51
|
|
|
{ |
52
|
|
|
if ($xml === null) { |
53
|
|
|
return false; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
$xml = simplexml_load_string($xml); |
57
|
|
|
|
58
|
|
|
$json = ''; |
59
|
|
|
|
60
|
|
|
// convert the XML structure into PHP array structure. |
61
|
|
|
$array = self::toArray($xml); |
62
|
|
|
|
63
|
|
|
if (($array !== null) && (sizeof($array) > 0)) { |
64
|
|
|
$json = json_encode($array); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
return $json; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* toArray. |
72
|
|
|
* |
73
|
|
|
* This function accepts a SimpleXmlElementObject as a single argument |
74
|
|
|
* and converts it into a PHP associative array. |
75
|
|
|
* If the input XML is in table format (i.e. non-nested), the resulting associative |
76
|
|
|
* array will also be in a table format. Conversely, if the input XML is in |
77
|
|
|
* tree (i.e. nested) format, this function will return an associative array |
78
|
|
|
* (tree/nested) representation of that XML. |
79
|
|
|
* |
80
|
|
|
* @param object Simple XML Element Object |
81
|
|
|
* @param int Recursion Depth |
82
|
|
|
* |
83
|
|
|
* @return array Returns assoc array containing the data from XML. Otherwise, returns null. |
|
|
|
|
84
|
|
|
*/ |
85
|
|
|
public static function toArray($xml, $recursionDepth = 0) |
86
|
|
|
{ |
87
|
|
|
// Keep an eye on how deeply we are involved in recursion. |
88
|
|
|
if ($recursionDepth > self::MAX_RECURSION_DEPTH_ALLOWED) { |
89
|
|
|
return; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
// we are at top/root level |
93
|
|
|
if ($recursionDepth === 0) { |
94
|
|
|
// If the external caller doesn't call this function initially |
95
|
|
|
// with a SimpleXMLElement object just return |
96
|
|
|
if (get_class($xml) !== 'SimpleXMLElement') { |
97
|
|
|
return; |
98
|
|
|
} else { // store original SimpleXmlElementObject sent by the caller. |
99
|
|
|
$provided_xml_object = $xml; |
|
|
|
|
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
if (is_a($xml, 'SimpleXMLElement')) { |
104
|
|
|
// Get a copy of the simpleXmlElementObject |
105
|
|
|
$copy_of_xml_object = $xml; |
|
|
|
|
106
|
|
|
// Get the object variables in the SimpleXmlElement object for us to iterate. |
107
|
|
|
$xml = get_object_vars($xml); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
// It needs to be an array of object variables. |
111
|
|
|
if (is_array($xml)) { |
112
|
|
|
// Initialize the result array. |
113
|
|
|
$resultArray = []; |
114
|
|
|
|
115
|
|
|
// Is the input array size 0? Then, we reached the rare CDATA text if any. |
116
|
|
|
if (count($xml) === 0) { |
117
|
|
|
// return the lonely CDATA. It could even be whitespaces. |
118
|
|
|
return (string) $copy_of_xml_object; |
|
|
|
|
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
// walk through the child elements now. |
122
|
|
|
foreach ($xml as $key => $value) { |
123
|
|
|
/* |
124
|
|
|
* Add Attributes to the results array ? |
125
|
|
|
*/ |
126
|
|
|
if (self::FETCH_ATTRIBUTES === false) { |
127
|
|
|
// check KEY - is it an attribute? |
128
|
|
|
if ((is_string($key)) && ($key === '@attributes')) { |
129
|
|
|
// yes, don't add, just continue with next element of foreach |
130
|
|
|
continue; |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
// increase the recursion depth by one. |
135
|
|
|
++$recursionDepth; |
136
|
|
|
|
137
|
|
|
// WATCH IT ! RECURSION !!! |
138
|
|
|
// recursively process the current (VALUE) element |
139
|
|
|
$resultArray[$key] = self::toArray($value, $recursionDepth); |
140
|
|
|
|
141
|
|
|
// decrease the recursion depth by one |
142
|
|
|
--$recursionDepth; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
// we are reaching the top/root level |
146
|
|
|
if ($recursionDepth === 0) { |
147
|
|
|
/* |
148
|
|
|
* Set the XML root element name as the root [top-level] key of |
149
|
|
|
* the associative array that we are going to return to the caller of this |
150
|
|
|
* recursive function. |
151
|
|
|
*/ |
152
|
|
|
$tempArray = $resultArray; |
153
|
|
|
$resultArray = []; |
154
|
|
|
$resultArray[$provided_xml_object->getName()] = $tempArray; |
|
|
|
|
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/* |
158
|
|
|
* Shifts every key/value pair of @attributes one level up and removes @attributes |
159
|
|
|
*/ |
160
|
|
|
if (self::FETCH_ATTRIBUTES && self::REMOVE_ATTRIBUTES_SUBLEVEL === true) { |
161
|
|
|
// ok, add attributes |
162
|
|
|
if (isset($resultArray['@attributes'])) { |
163
|
|
|
// but as key => value elements |
164
|
|
|
foreach ($resultArray['@attributes'] as $key => $value) { |
165
|
|
|
$resultArray[$key] = $value; |
166
|
|
|
} |
167
|
|
|
// removing @attributes |
168
|
|
|
unset($resultArray['@attributes']); |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return $resultArray; |
173
|
|
|
} else { |
174
|
|
|
// it's is either the XML attribute text or text between XML tags |
175
|
|
|
return (string) $xml; |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.