1<?php 2/** 3 * Classes and functions for manipulating XML templates. 4 * 5 * @author The phpLDAPadmin development team 6 * @package phpLDAPadmin 7 */ 8 9/** 10 * XML Parser 11 * 12 * This will read our XML file and convert it into variables for us to parse. 13 * 14 * @package phpLDAPadmin 15 * @subpackage XML 16 */ 17class xml2array { 18 var $stack = array(); 19 var $stack_ref; 20 var $arrOutput = array(); 21 var $resParser; 22 var $strXmlData; 23 24 private function push_pos(&$pos) { 25 $this->stack[count($this->stack)] = &$pos; 26 $this->stack_ref = &$pos; 27 } 28 29 private function pop_pos() { 30 unset($this->stack[count($this->stack) - 1]); 31 $this->stack_ref = &$this->stack[count($this->stack) - 1]; 32 } 33 34 public function parseXML($strInputXML,$filename) { 35 $this->resParser = xml_parser_create(); 36 xml_set_object($this->resParser,$this); 37 xml_set_element_handler($this->resParser,'tagOpen','tagClosed'); 38 39 xml_set_character_data_handler($this->resParser,'tagData'); 40 41 $this->push_pos($this->arrOutput); 42 43 $this->strXmlData = xml_parse($this->resParser,$strInputXML); 44 45 if (! $this->strXmlData) 46 die(sprintf('XML error: %s at line %d in file %s', 47 xml_error_string(xml_get_error_code($this->resParser)), 48 xml_get_current_line_number($this->resParser), 49 $filename)); 50 51 xml_parser_free($this->resParser); 52 53 $output = array(); 54 foreach ($this->arrOutput as $key => $values) 55 $output[$key] = $this->cleanXML($values); 56 57 #return $this->arrOutput; 58 return $output; 59 } 60 61 private function tagOpen($parser,$name,$attrs) { 62 $name = strtolower($name); 63 64 if (isset($this->stack_ref[$name])) { 65 if (! isset($this->stack_ref[$name][0])) { 66 $tmp = $this->stack_ref[$name]; 67 unset($this->stack_ref[$name]); 68 $this->stack_ref[$name][0] = $tmp; 69 } 70 71 $cnt = count($this->stack_ref[$name]); 72 $this->stack_ref[$name][$cnt] = array(); 73 if (isset($attrs)) 74 $this->stack_ref[$name][$cnt] = $attrs; 75 76 $this->push_pos($this->stack_ref[$name][$cnt]); 77 78 } else { 79 $this->stack_ref[$name]=array(); 80 81 if (isset($attrs)) 82 $this->stack_ref[$name]=$attrs; 83 84 $this->push_pos($this->stack_ref[$name]); 85 } 86 } 87 88 private function tagData($parser,$tagData) { 89 if (trim($tagData) != '') { 90 91 if (isset($this->stack_ref['#text'])) 92 $this->stack_ref['#text'] .= $tagData; 93 else 94 $this->stack_ref['#text'] = $tagData; 95 } 96 } 97 98 private function tagClosed($parser,$name) { 99 $this->pop_pos(); 100 } 101 102 /** 103 * This function will parse an XML array and make a normal array. 104 * 105 * @return array - Clean XML data 106 */ 107 private function cleanXML($details) { 108 # Quick processing for the final branch of the XML array. 109 if (is_array($details) && isset($details['#text'])) 110 return $details['#text']; 111 112 elseif (is_array($details) && isset($details['ID']) && count($details) == 1) 113 return $details['ID']; 114 115 $cleanXML = array(); 116 117 # Quick processing for the final branch, when it holds the ID and values. 118 if (is_array($details) && isset($details['ID']) && count($details) > 1) { 119 $key = $details['ID']; 120 unset($details['ID']); 121 $cleanXML[$key] = $this->cleanXML($details); 122 $details = array(); 123 } 124 125 # More detailed processing... 126 if (is_array($details)) 127 foreach ($details as $key => $values) 128 if (is_numeric($key) && isset($values['ID']) && count($values) > 1) { 129 $key = $values['ID']; 130 unset($values['ID']); 131 $cleanXML[$key] = $this->cleanXML($values); 132 133 } elseif (isset($values['#text'])) 134 $cleanXML[$key] = $this->cleanXML($values); 135 136 elseif (is_array($values)) 137 $cleanXML[$key] = $this->cleanXML($values); 138 139 if (! $cleanXML) 140 return $details; 141 else 142 return $cleanXML; 143 } 144} 145