code.') '.trim($error->message), $error->line, $error->column ))); } } $xml = new XMLReader(); $xml->xml($string); $data = $this->xml_to_array($xml); $xml->close(); return $data; } /** * Method for recursive processing of xml dom nodes. * * @param XMLReader $xml * @param string $path * * @return array|string */ protected function xml_to_array(XMLReader $xml, $path = '') { $data = null; while ($xml->read()) { switch ($xml->nodeType) { case XMLReader::ELEMENT: if ($data === null) { $data = []; } elseif (!is_array($data)) { throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _s('unexpected text "%1$s"', trim($data)) )); } $node_name = $xml->name; $sub_path = $path.'/'.$node_name; if (array_key_exists($node_name, $data)) { $node_name .= count($data); $sub_path .= '('.count($data).')'; } /* * A special case for 1.8 import where attributes are still used attributes must be added to the * array as if they where child elements. */ if ($xml->hasAttributes) { while ($xml->moveToNextAttribute()) { $data[$node_name][$xml->name] = $xml->value; } // it makes $this->isEmptyElement valid after processing attributes $xml->moveToElement(); /* * We assume that an element with attributes always contains child elements, not a text node * works for 1.8 XML. */ if (!$xml->isEmptyElement) { $child_data = $this->xml_to_array($xml, $sub_path); if (is_array($child_data)) { foreach ($child_data as $child_node_name => $child_node_value) { if (array_key_exists($child_node_name, $data[$node_name])) { $child_node_name .= count($data[$node_name]); } $data[$node_name][$child_node_name] = $child_node_value; } } elseif ($child_data !== '') { throw new Exception(_s('Invalid tag "%1$s": %2$s.', $sub_path, _s('unexpected text "%1$s"', trim($child_data)) )); } } } else { $data[$node_name] = $xml->isEmptyElement ? '' : $this->xml_to_array($xml, $sub_path); } break; case XMLReader::CDATA: // falls through case XMLReader::TEXT: if ($data === null) { $data = $xml->value; } elseif (is_array($data)) { throw new Exception(_s('Invalid tag "%1$s": %2$s.', $path, _s('unexpected text "%1$s"', trim($xml->value)) )); } break; case XMLReader::END_ELEMENT: /* * For tags with empty value: . */ if ($data === null) { $data = ''; } return $data; } } return $data; } }