FusionDirectory
 All Data Structures Files Functions Variables
class_xml.inc
Go to the documentation of this file.
1 <?php
2 /*
3  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
4  Copyright (C) 2003-2010 Cajus Pollmeier
5  Copyright (C) 2011-2016 FusionDirectory
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
31 class xml {
41  static function xml2array($contents, $get_attributes = 1, $priority = 'tag')
42  {
43  if (!$contents) {
44  return array();
45  }
46 
47  if (!function_exists('xml_parser_create')) {
48  trigger_error('xml_parser_create function does not exists');
49  return array();
50  }
51 
52  //Get the XML parser of PHP - PHP must have this module for the parser to work
53  $parser = xml_parser_create('');
54  xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8"); // http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
55  xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
56  xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
57  xml_parse_into_struct($parser, trim($contents), $xml_values);
58  xml_parser_free($parser);
59 
60  if (!$xml_values) {
61  return;//Hmm...
62  }
63 
64  //Initializations
65  $xml_array = array();
66 
67  $current = &$xml_array; //Refference
68 
69  //Go through the tags.
70  $repeated_tag_index = array();//Multiple tags with same name will be turned into an array
71  foreach ($xml_values as $data) {
72  unset($attributes, $value);//Remove existing values, or there will be trouble
73 
74  //This command will extract these variables into the foreach scope
75  // tag(string), type(string), level(int), attributes(array).
76  extract($data);//We could use the array by itself, but this cooler.
77 
78  $result = array();
79  $attributes_data = array();
80 
81  if (isset($value)) {
82  if ($priority == 'tag') {
83  $result = $value;
84  } else {
85  //Put the value in a assoc array if we are in the 'Attribute' mode
86  $result['value'] = $value;
87  }
88  }
89 
90  //Set the attributes too.
91  if (isset($attributes) and $get_attributes) {
92  foreach ($attributes as $attr => $val) {
93  if ($priority == 'tag') {
94  $attributes_data[$attr] = $val;
95  } else {
96  //Set all the attributes in a array called 'attr'
97  $result['attr'][$attr] = $val;
98  }
99  }
100  }
101 
102  //See tag status and do the needed.
103  if ($type == "open") {//The starting of the tag '<tag>'
104  $parent[$level - 1] = &$current;
105  if (!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag
106  $current[$tag] = $result;
107  if ($attributes_data) {
108  $current[$tag. '_attr'] = $attributes_data;
109  }
110  $repeated_tag_index[$tag.'_'.$level] = 1;
111 
112  $current = &$current[$tag];
113 
114  } else { //There was another element with the same tag name
115 
116  if (isset($current[$tag][0])) {//If there is a 0th element it is already an array
117  $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
118  $repeated_tag_index[$tag.'_'.$level]++;
119  } else {//This section will make the value an array if multiple tags with the same name appear together
120  $current[$tag] = array($current[$tag],$result);//This will combine the existing item and the new item together to make an array
121  $repeated_tag_index[$tag.'_'.$level] = 2;
122 
123  if (isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well
124  $current[$tag]['0_attr'] = $current[$tag.'_attr'];
125  unset($current[$tag.'_attr']);
126  }
127  }
128  $last_item_index = $repeated_tag_index[$tag.'_'.$level] - 1;
129  $current = &$current[$tag][$last_item_index];
130  }
131 
132  } elseif ($type == "complete") { //Tags that ends in 1 line '<tag />'
133  //See if the key is already taken.
134  if (!isset($current[$tag])) { //New Key
135  $current[$tag] = $result;
136  $repeated_tag_index[$tag.'_'.$level] = 1;
137  if ($priority == 'tag' and $attributes_data) {
138  $current[$tag. '_attr'] = $attributes_data;
139  }
140  } else { //If taken, put all things inside a list(array)
141  if (isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array...
142  // ...push the new element into that array.
143  $current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
144 
145  if ($priority == 'tag' and $get_attributes and $attributes_data) {
146  $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
147  }
148  $repeated_tag_index[$tag.'_'.$level]++;
149 
150  } else { //If it is not an array...
151  $current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
152  $repeated_tag_index[$tag.'_'.$level] = 1;
153  if ($priority == 'tag' and $get_attributes) {
154  if (isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well
155  $current[$tag]['0_attr'] = $current[$tag.'_attr'];
156  unset($current[$tag.'_attr']);
157  }
158 
159  if ($attributes_data) {
160  $current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
161  }
162  }
163  $repeated_tag_index[$tag.'_'.$level]++; //0 and 1 index is already taken
164  }
165  }
166  } elseif ($type == 'close') { //End of tag '</tag>'
167  $current = &$parent[$level - 1];
168  }
169  }
170 
171  return $xml_array;
172  }
173 
174 }
This class contains all the function needed to manage xml files.
Definition: class_xml.inc:31
static xml2array($contents, $get_attributes=1, $priority= 'tag')
Transform a xml document to an array.
Definition: class_xml.inc:41