"", "xhtml1-transitional" => "" ); public function setDataItem($key, $val) { $this->data[$key] = $val; } public function getDataItem($key) { if (!isset($this->data[$key])) return False; return $this->data[$key]; } public function getFreeID() { return $this->freeid++; } public function setBeforeParseCallback($callback) { if (!is_callable($callback)) return False; $this->beforeparsexml = $callback; } public function addReplacement($callback, $key = False) { if (!is_callable($callback)) return False; if (!$key) { $key = "replacementnr++)." />"; } $this->replacements[$key] = $callback; return $key; } public function addFunction($callback) { if (!is_callable($callback)) return False; $this->workafterwards[] = $callback; } public function setProtocol($key, $val) { // i. e. "callback:db://" => array($dbclass, "getvalue") if (substr($key, 0, 9) == "callback:" && !is_callable($val)) return False; $this->protocols[$key] = $val; } public function output($xml, $returntype = "xhtml", $doctype = "xhtml1-strict") { foreach(get_declared_classes() as $class) { if (substr($class,0,4) == "xml_") { $this->tags[] = substr($class, 4); } } $this->returntype = $returntype; $this->xml = $xml; $output = xml::parse($this->xml); $this->xml = $output["content_string"]; if (isset($this->doctypes[$doctype])) { $doctype = $this->doctypes[$doctype]; } if ($doctype != "") { $this->xml = "\n".$doctype."\n".$this->xml; } foreach($this->workafterwards as $function) { $this->xml = call_user_func($function, $this->xml); } foreach($this->replacements as $key => $val) { $val = call_user_func($val, $this->xml); $this->xml = str_replace($key, $val, $this->xml); } $this->xml = str_replace(" clear=\"none\"", "", $this->xml); $this->xml = str_replace(" rowspan=\"1\" colspan=\"1\"", "", $this->xml); return $this->xml; } public function url($url) { foreach($this->protocols as $protocol => $replace) { if (substr($protocol, 0, 9) == "callback:") { $callback = True; $protocol = substr($protocol, 9); } else { $callback = False; } if (substr($url, 0, strlen($protocol)) == $protocol) { $url = substr($url, strlen($protocol)); if ($callback) { $protocol = call_user_func($replace, $url); } else { $protocol = str_replace("%s", $url, $replace); $protocol = str_replace("%u", urlencode($url), $protocol); } return $protocol; } } return $url; } public static function mask_xml($xml) { return xml::mask(utf8_encode($xml)); } public static function mask($xml) { $xml = htmlspecialchars($xml, ENT_QUOTES); return preg_replace("/�*39;/", "'", $xml); } public function parse($xml, $onlychilds = False) { $xml = call_user_func($this->beforeparsexml, $xml); if (substr(trim($xml), 0, 1) != "<") { $xml = "
".$xml."
"; $onlychilds = True; } if (substr(trim($xml), 0, 6) != "\n".$xml; } $dom = new DomDocument(); $dom->resolveExternals = True; if (!$dom->loadXML($xml)) { $xml = explode("\n", self::mask($xml)); echo "
\n";
            $i = 1;
            foreach($xml as $line)
            {
                echo $i.": ".$line."\n";
                $i++;
            }
            echo "
"; throw InvalidXMLException("Invalid XML."); } $xml = $this->parseNode($dom->documentElement, $onlychilds); return $xml; } public function parseNode ( $node , $onlychilds = False , $returncontent = True , $xmlfuncs = True , $attributes = array(), $tags = array(), $level = 0 ) { $workthroughchilds = False; $content_string = "" ; $attributes_string = "" ; $attributes_array = array(); $tags_array = array(); $childnodes = $node->childNodes; if ($node->nodeType == XML_TEXT_NODE) $content_string = xml::mask($node->nodeValue); elseif ($node->nodeType == XML_COMMENT_NODE) $content_string = ""; elseif ($node->nodeType == XML_CDATA_SECTION_NODE) $content_string = "nodeValue."]]>"; else if ($node->nodeType == XML_ENTITY_REF_NODE) $content_string = $node->textContent; else $workthroughchilds = True; if (!$workthroughchilds) { return array ( "content_string" => $content_string , "attributes_string" => $attributes_string, "attributes_array" => $attributes_array , "tags_array" => $tags_array ); } foreach($childnodes as $child) { if ($child->nodeName == "parentattr") { $content = self::parseNode ( $child , True , True , $xmlfuncs ); $attributes_array[$child->getAttribute("name")] = $this->url($content["content_string"]); } else if ($tags == "*" || in_array($child->nodeName, $tags)) { if ($child->nodeName[0] == "#") continue; if ($level == 0) { $data = $this->parseNode ( $child , True , True , $xmlfuncs ); } else { $data = $this->parseNode ( $child , True , True , $xmlfuncs , array() , "*" , $level - 1 ); $data["content_string"] = $data["tags_array"]; } if (!isset($tags_array[$child->nodeName])) $tags_array[$child->nodeName] = array(); $tags_array[$child->nodeName][] = array("content" => $data["content_string"], "attributes" => $data["attributes_array"], "node" => $child); } else if ($returncontent && $xmlfuncs && in_array($child->nodeName, $this->tags)) { $class = "xml_".$child->nodeName; $class = new $class($child, $this); $output = $class->output($this->returntype); if (is_array($output) && isset($output["reparse"])) { $output = $this->parse("".$output["output"]."", True); $output = $output["content_string"]; } $content_string .= $output; } elseif ($returncontent) { $data = $this->parseNode ( $child , False , True , $xmlfuncs , $attributes ); $content_string .= $data["content_string"]; } } if (is_object($node->attributes)) { for($i=0; $attribute = $node->attributes->item($i); $i++) { if (!$attribute) { break; } $attributes_array[$attribute->nodeName] = $this->url($attribute->nodeValue); } } $inside = in_array($node->nodeName, $this->a_inside ); $outside = in_array($node->nodeName, $this->a_outside); if (is_array($attributes)) { foreach($attributes_array as $key => $val) { if (in_array($key, $attributes) || (($inside || $outside) && $key == "href")) { continue; } $attributes_string .= " ".$key."=\"".self::mask($val)."\""; unset($attributes_array[$key]); } foreach($attributes as $key) { if (!isset($attributes_array[$key])) { $attributes_array[$key] = ""; } } } if (!$onlychilds) { if ($content_string == "" && !in_array($node->nodeName, $this->forcechildnodes)) { $content_string = $this->href("<".$node->nodeName.$attributes_string." />", "", $attributes_array); } else { if ($inside || $outside) { $xml_string = "<".$node->nodeName.$attributes_string.">%snodeName.">"; $content_string = $this->href($xml_string, $content_string, $attributes_array, $inside); } else { $content_string = "<".$node->nodeName.$attributes_string.">".$content_string."nodeName.">"; } } } return array ( "content_string" => $content_string , "attributes_string" => $attributes_string, "attributes_array" => $attributes_array , "tags_array" => $tags_array ); } public function attributes($node, $attributes = array()) { return $this->parseNode($node, True, False, True, $attributes); } public function href($xml, $content, $attributes, $child = False) { if (!isset($attributes["href"]) || $attributes["href"] == "") { $xml = str_replace("%s", $content, $xml); return $xml; } $rule = "url($attributes["href"]))."\">%s"; if (!$child) { $xml = str_replace("%s", $content, $xml ); $xml = str_replace("%s", $xml , $rule); return $xml; } $xml = str_replace("%s", $rule , $xml); $xml = str_replace("%s", $content, $xml); return $xml; } } ?>