class_xml.inc 6.86 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2003-2010  Cajus Pollmeier
  Copyright (C) 2011-2020  FusionDirectory
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
/*!
 * \file class_xml.inc
 * Source code for class xml
/*!
 * \brief This class contains all the function needed to manage xml
 * files
class xml
  /*!
   * \brief Transform a xml document to an array
   * \param $contents Contents
   * \param integer $get_attributes Initialized at 1
   * \param string $priority Initialized at 'tag'
  static function xml2array ($contents, $get_attributes = 1, $priority = 'tag')
    if (!$contents) {
      return [];
    if (!function_exists('xml_parser_create')) {
      trigger_error('xml_parser_create function does not exists');
      return [];
    //Get the XML parser of PHP - PHP must have this module for the parser to work
    $parser = xml_parser_create('');
    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
    xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
    xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
    xml_parse_into_struct($parser, trim($contents), $xml_values);
    xml_parser_free($parser);
    if (!$xml_values) {
      return;
    // Initializations
    $xml_array    = [];
    // Reference
    $current = &$xml_array;
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
// Go through the tags. // Multiple tags with same name will be turned into an array $repeated_tag_index = []; foreach ($xml_values as $data) { $result = []; $attributes_data = []; if (isset($data['value'])) { if ($priority == 'tag') { $result = $data['value']; } else { // Put the value in a assoc array if we are in the 'Attribute' mode $result['value'] = $data['value']; } } //Set the attributes too. if (isset($data['attributes']) and $get_attributes) { foreach ($data['attributes'] as $attr => $val) { if ($priority == 'tag') { $attributes_data[$attr] = $val; } else { // Set all the attributes in a array called 'attr' $result['attr'][$attr] = $val; } } } // See tag status and do the needed. if ($data['type'] == 'open') { // The starting of the tag '<tag>' $parent[$data['level'] - 1] = &$current; if (!is_array($current) or (!in_array($data['tag'], array_keys($current)))) { // Insert New tag $current[$data['tag']] = $result; if ($attributes_data) { $current[$data['tag']. '_attr'] = $attributes_data; } $repeated_tag_index[$data['tag'].'_'.$data['level']] = 1; $current = &$current[$data['tag']]; } else { // There was another element with the same tag name if (isset($current[$data['tag']][0])) { // If there is a 0th element it is already an array $current[$data['tag']][$repeated_tag_index[$data['tag'].'_'.$data['level']]] = $result; $repeated_tag_index[$data['tag'].'_'.$data['level']]++; } else { // This section will make the value an array if multiple tags with the same name appear together // This will combine the existing item and the new item together to make an array $current[$data['tag']] = [$current[$data['tag']],$result]; $repeated_tag_index[$data['tag'].'_'.$data['level']] = 2; if (isset($current[$data['tag'].'_attr'])) { // The attribute of the last(0th) tag must be moved as well $current[$data['tag']]['0_attr'] = $current[$data['tag'].'_attr']; unset($current[$data['tag'].'_attr']); } } $last_item_index = $repeated_tag_index[$data['tag'].'_'.$data['level']] - 1; $current = &$current[$data['tag']][$last_item_index]; } } elseif ($data['type'] == "complete") { // Tags that ends in 1 line '<tag />' // See if the key is already taken. if (!isset($current[$data['tag']])) { // New Key $current[$data['tag']] = $result;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
$repeated_tag_index[$data['tag'].'_'.$data['level']] = 1; if ($priority == 'tag' and $attributes_data) { $current[$data['tag']. '_attr'] = $attributes_data; } } else { // If taken, put all things inside a list(array) if (isset($current[$data['tag']][0]) and is_array($current[$data['tag']])) { // If it is already an array... // ...push the new element into that array. $current[$data['tag']][$repeated_tag_index[$data['tag'].'_'.$data['level']]] = $result; if ($priority == 'tag' and $get_attributes and $attributes_data) { $current[$data['tag']][$repeated_tag_index[$data['tag'].'_'.$data['level']] . '_attr'] = $attributes_data; } $repeated_tag_index[$data['tag'].'_'.$data['level']]++; } else { //If it is not an array... //...Make it an array using using the existing value and the new value $current[$data['tag']] = [$current[$data['tag']],$result]; $repeated_tag_index[$data['tag'].'_'.$data['level']] = 1; if ($priority == 'tag' and $get_attributes) { if (isset($current[$data['tag'].'_attr'])) { // The attribute of the last(0th) tag must be moved as well $current[$data['tag']]['0_attr'] = $current[$data['tag'].'_attr']; unset($current[$data['tag'].'_attr']); } if ($attributes_data) { $current[$data['tag']][$repeated_tag_index[$data['tag'].'_'.$data['level']] . '_attr'] = $attributes_data; } } // 0 and 1 index is already taken $repeated_tag_index[$data['tag'].'_'.$data['level']]++; } } } elseif ($data['type'] == 'close') { // End of tag '</tag>' $current = &$parent[$data['level'] - 1]; } } return $xml_array; } }