forked from moodle/moodle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xmlize.php
189 lines (152 loc) · 5.19 KB
/
xmlize.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
/**
* xmlize.php - xmlize() is by Hans Anderson, {@link http://www.hansanderson.com/contact/}
*
* Ye Ole "Feel Free To Use it However" License [PHP, BSD, GPL].
* some code in xml_depth is based on code written by other PHPers
* as well as one Perl script. Poor programming practice and organization
* on my part is to blame for the credit these people aren't receiving.
* None of the code was copyrighted, though.
*
* @author Hans Anderson
* @version This is a stable release, 1.0. I don't foresee any changes, but you
* might check {@link http://www.hansanderson.com/php/xml/} to see
* @package moodlecore
*/
/**
* Create xml formatted output from an array.
*
* usage:<br>
* <code>
* $xml = xmlize($array);
* </code>
* See the function {@link traverse_xmlize()} for information about the
* structure of the array, it's much easier to explain by showing you.
* Be aware that the array is somewhat tricky. I use xmlize all the time,
* but still need to use {@link traverse_xmlize()} quite often to show me the structure!
*
* THIS IS A PHP 5 VERSION:
*
* This modified version basically has a new optional parameter
* to specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
* I recommend you to read this PHP bug. There you can see how PHP4, PHP5.0.0
* and PHP5.0.2 will handle this.
* {@link http://bugs.php.net/bug.php?id=29711}
* Ciao, Eloy :-)
*
*
* @author Hans Anderson
* @param array $data The array to be converted
* @param int $WHITE If set to 1 allows the parser to skip "space" characters in xml document. Default is 0
* @param string $encoding Specify an OUTPUT encoding. If not specified, it defaults to UTF-8.
* @return array
*/
function xmlize($data, $WHITE=1, $encoding='UTF-8') {
$data = trim($data);
$vals = $index = $array = array();
$parser = xml_parser_create($encoding);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, $WHITE);
xml_parse_into_struct($parser, $data, $vals, $index);
xml_parser_free($parser);
$i = 0;
$tagname = $vals[$i]['tag'];
if ( isset ($vals[$i]['attributes'] ) )
{
$array[$tagname]['@'] = $vals[$i]['attributes'];
} else {
$array[$tagname]['@'] = array();
}
$array[$tagname]["#"] = xml_depth($vals, $i);
return $array;
}
/**
* @internal You don't need to do anything with this function, it's called by
* xmlize. It's a recursive function, calling itself as it goes deeper
* into the xml levels. If you make any improvements, please let me know.
* @access private
*/
function xml_depth($vals, &$i) {
$children = array();
if ( isset($vals[$i]['value']) )
{
array_push($children, $vals[$i]['value']);
}
while (++$i < count($vals)) {
switch ($vals[$i]['type']) {
case 'open':
if ( isset ( $vals[$i]['tag'] ) )
{
$tagname = $vals[$i]['tag'];
} else {
$tagname = '';
}
if ( isset ( $children[$tagname] ) )
{
$size = sizeof($children[$tagname]);
} else {
$size = 0;
}
if ( isset ( $vals[$i]['attributes'] ) ) {
$children[$tagname][$size]['@'] = $vals[$i]["attributes"];
}
$children[$tagname][$size]['#'] = xml_depth($vals, $i);
break;
case 'cdata':
array_push($children, $vals[$i]['value']);
break;
case 'complete':
$tagname = $vals[$i]['tag'];
if( isset ($children[$tagname]) )
{
$size = sizeof($children[$tagname]);
} else {
$size = 0;
}
if( isset ( $vals[$i]['value'] ) )
{
$children[$tagname][$size]["#"] = $vals[$i]['value'];
} else {
$children[$tagname][$size]["#"] = '';
}
if ( isset ($vals[$i]['attributes']) ) {
$children[$tagname][$size]['@']
= $vals[$i]['attributes'];
}
break;
case 'close':
return $children;
break;
}
}
return $children;
}
/**
* This helps you understand the structure of the array {@link xmlize()} outputs
*
* Function by [email protected], a HUGE help!<br>
* Usage:<br>
* <code>
* traverse_xmlize($xml, 'xml_');
* print '<pre>' . implode("", $traverse_array . '</pre>';
* </code>
* @author [email protected]
* @param array $array ?
* @param string $arrName ?
* @param int $level ?
* @return int
* @todo Finish documenting this function
*/
function traverse_xmlize($array, $arrName = 'array', $level = 0) {
foreach($array as $key=>$val)
{
if ( is_array($val) )
{
traverse_xmlize($val, $arrName . '[' . $key . ']', $level + 1);
} else {
$GLOBALS['traverse_array'][] = '$' . $arrName . '[' . $key . '] = "' . $val . "\"\n";
}
}
return 1;
}
?>