3 * Reads XML documents into a multi dimensional Array.
\r
5 * @version $Id: PhpdocXMLReader.php,v 1.2 2000/12/03 22:37:38 uw Exp $
\r
7 class PhpdocXMLReader extends PhpdocObject {
\r
10 * PHPDocFileHandler object.
\r
12 * @var object PhpdocFileHandler
\r
13 * @see createFileHandler()
\r
18 * Values array from xml_parse_into_struct().
\r
21 * @see parse(), stripCloseFromStructvalues(), importXML()
\r
23 var $structvalues = array();
\r
26 * Parses a given XML file and returns the data as a hash.
\r
28 * Please do not ask me for a in detail explanation of how it is done,
\r
29 * the documentation is in the source...
\r
31 * @param string $filename Name of the xml document
\r
33 * @throws PhpdocError
\r
36 function parse($filename) {
\r
38 if (""==$filename) {
\r
39 $this->err[] = new PhpdocError("No filename given.", __FILE__, __LINE__);
\r
43 $parser = @xml_parser_create();
\r
45 $this->err = PhpdocError("Can't create a XML Parser.", __FILE__, __LINE__);
\r
48 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
\r
50 $this->createFileHandler();
\r
51 $xml = $this->filehandler->getFile($filename);
\r
55 xml_parse_into_struct($parser, $xml, &$values, &$index);
\r
57 xml_parser_free($parser);
\r
59 $this->structvalues = $values;
\r
60 $this->stripCloseFromStructvalues();
\r
61 list($data, $last) = $this->importXML();
\r
62 $this->structvalues = array();
\r
68 * Creates a PhpdocFileHandler object and saves it to $filehandler if it does not already exist.
\r
72 function createFilehandler() {
\r
74 if (!isset($this->filehandler))
\r
75 $this->filehandler = new PhpdocFileHandler;
\r
77 } // end func createFilehandler
\r
80 * Strips all values out of the xml_parse_intro_struct() values array with the type "open".
\r
82 * @see $structvalues
\r
84 function stripCloseFromStructvalues() {
\r
88 reset($this->structvalues);
\r
89 while (list($k, $v) = each($this->structvalues))
\r
90 if ("close" != $v["type"])
\r
93 $this->structvalues = $values;
\r
94 } // end func stripCloseFromStructvalues
\r
97 * Converts an xml_parse_into_struct value array to an array that's simmilar to phpdocs internal arrays.
\r
99 * Well, don't ask me to explain this hack. Just take it as it. For those who want to unterstand and optimize
\r
101 * - PHP3 compatibility is a must
\r
103 * - no eval(), this can't be optimized by the compiler
\r
107 * @return array $data[0] = daten, $data[1] = some index value used for the recursion
\r
108 * @see addToArray()
\r
110 function importXML($start = 0, $allowed_level = 1) {
\r
115 for ($i=$start; $i<count($this->structvalues); $i++) {
\r
116 if ($allowed_level != $this->structvalues[$i]["level"])
\r
119 $value = (isset($this->structvalues[$i]["value"])) ? $this->structvalues[$i]["value"] : "";
\r
120 $attribs = (isset($this->structvalues[$i]["attributes"])) ? $this->structvalues[$i]["attributes"] : "";
\r
121 $tag = $this->structvalues[$i]["tag"];
\r
123 if ("open" == $this->structvalues[$i]["type"]) {
\r
125 list($inner, $next) = $this->importXML($i+1, $this->structvalues[$i]["level"]+1);
\r
127 // append the inner data to the current one
\r
128 $data = $this->addToArray($data, $tag, $value, $attribs, $inner);
\r
130 // skip some entries in $this->structvalues
\r
135 // same level, append to the array
\r
136 $data = $this->addToArray($data, $tag, $value, $attribs);
\r
140 // remember the last index in $this->structvalues we've worked on
\r
144 return array($data, $last);
\r
145 } // end func importXML
\r
148 * Appends some values to an array
\r
149 * Well, don't ask me; just improve it with the remarks on buildXMLResult()
\r
155 * @return array $target
\r
157 function addToArray($target, $key, $value="", $attributes = "", $inner = "") {
\r
159 if (!isset($target[$key]["value"]) && !isset($target[$key][0])) {
\r
162 $target[$key] = $inner;
\r
164 if (""!=$attributes) {
\r
165 reset($attributes);
\r
166 while (list($k, $v) = each($attributes))
\r
167 $target[$key][$k] = $this->xmldecode($v);
\r
170 $target[$key]["value"] = $this->xmldecode($value);
\r
174 if (!isset($target[$key][0])) {
\r
176 $oldvalue = $target[$key];
\r
177 $target[$key] = array();
\r
178 $target[$key][0] = $oldvalue;
\r
181 $target[$key][1] = $inner;
\r
183 if ("" != $attributes) {
\r
184 reset($attributes);
\r
185 while (list($k, $v)=each($attributes))
\r
186 $target[$key][1][$k] = $this->xmldecode($v);
\r
189 $target[$key][1]["value"] = $this->xmldecode($value);
\r
193 $index = count($target[$key]);
\r
196 $target[$key][$index] = $inner;
\r
198 if (""!=$attributes) {
\r
199 reset($attributes);
\r
200 while (list($k, $v) = each($attributes))
\r
201 $target[$key][$index][$k] = $this->xmldecode($v);
\r
204 $target[$key][$index]["value"] = $this->xmldecode($value);
\r
211 } // end func addToArray
\r
214 * Replaces some basic entities with their character counterparts.
\r
216 * @param string String to decode
\r
217 * @return string Decoded string
\r
219 function xmldecode($value) {
\r
220 #return preg_replace( array("@<@", "@>@", "@'@", "@"@", "@&@"), array("<", ">", "'", '"', "&"), $value);
\r
221 return utf8_decode(preg_replace( array("@<@", "@>@", "@'@", "@"@", "@&@"), array("<", ">", "'", '"', "&"), $value));
\r
222 } // end func xmldecode
\r
224 } // end class PhpdocXMLReader
\r