00001 <?
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 if (__FILE__ == $PATH_TRANSLATED) {
00027 header("Status: 403 Forbidden");
00028 exit();
00029 }
00030
00031
00032 class xml_simple {
00033
00034 var $tree = array();
00035 var $force_to_array = array();
00036
00037 var $error = null;
00038
00039
00040 function xml_simple($encoding = 'UTF-8') {
00041 $this->parser = xml_parser_create($encoding);
00042 xml_set_object($this->parser, &$this);
00043 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
00044 xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, 1);
00045 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
00046 xml_set_element_handler($this->parser, "start_element", "stop_element");
00047 xml_set_character_data_handler($this->parser, "char_data");
00048 }
00049
00050 function force_to_array() {
00051 for ($i = 0; $i < func_num_args(); $i++) {
00052 $this->force_to_array[] = func_get_arg($i);
00053 }
00054 }
00055
00056
00057 function parse($data) {
00058 $this->tree = array();
00059
00060 if (!xml_parse($this->parser, $data, 1)) {
00061 $this->error = "xml parse error: " .
00062 xml_error_string(xml_get_error_code($this->parser)) .
00063 " on line ".xml_get_current_line_number($this->parser);
00064 return false;
00065 }
00066 return $this->tree[0]["content"];
00067 }
00068
00069 function parse_file($file) {
00070 $fp = @fopen($file, "r");
00071 if (!$fp) {
00072 user_error("unable to open file: '$file'");
00073 return false;
00074 }
00075 while ($data = fread($fp, 4096)) {
00076 if (!xml_parse($this->parser, $data, feof($fp))) {
00077 user_error("xml parse error: " .
00078 xml_error_string(xml_get_error_code($this->parser)) .
00079 " on line " . xml_get_current_line_number($this->parser));
00080 }
00081 }
00082 fclose($fp);
00083 return $this->tree[0]["content"];
00084 }
00085
00086 function encode_as_xml($value) {
00087 if (is_array($value)) {
00088 reset($value); $out = '';
00089 while (list($key,$val) = each($value)) {
00090 if (is_array($val) && isset($val[0])) {
00091 reset($val);
00092 while (list(,$item) = each($val)) {
00093 $out .= "<$key>".xml_simple::encode_as_xml($item)."</$key>";
00094 }
00095 } else {
00096 $out .= "<$key>".xml_simple::encode_as_xml($val)."</$key>";
00097 }
00098 }
00099 return $out;
00100 } else {
00101 return htmlspecialchars($value);
00102 }
00103 }
00104
00105 function start_element($parser, $name, $attrs) {
00106 array_unshift($this->tree, array("name" => $name));
00107 }
00108
00109 function stop_element($parser, $name) {
00110 if ($name != $this->tree[0]["name"]) die("incorrect nesting");
00111 if (count($this->tree) > 1) {
00112 $elem = array_shift($this->tree);
00113 if (isset($this->tree[0]["content"][$elem["name"]])) {
00114 if (is_array($this->tree[0]["content"][$elem["name"]]) && isset($this->tree[0]["content"][$elem["name"]][0])) {
00115 array_push($this->tree[0]["content"][$elem["name"]], $elem["content"]);
00116 } else {
00117 $this->tree[0]["content"][$elem["name"]] =
00118 array($this->tree[0]["content"][$elem["name"]],$elem["content"]);
00119 }
00120 } else {
00121 if (in_array($elem["name"],$this->force_to_array)) {
00122 $this->tree[0]["content"][$elem["name"]] = array($elem["content"]);
00123 } else {
00124 if (!isset($elem["content"])) $elem["content"] = "";
00125 $this->tree[0]["content"][$elem["name"]] = $elem["content"];
00126 }
00127 }
00128 }
00129 }
00130
00131 function char_data($parser, $data) {
00132 # don't add a string to non-string data
00133 if (!is_string($this->tree[0]["content"]) && !preg_match("/\\S/", $data)) return;
00134 $this->tree[0]["content"] .= $data;
00135 }
00136 }