Chris@0: 'html', Chris@0: 'http://www.w3.org/1998/Math/MathML' => 'math', Chris@17: 'http://www.w3.org/2000/svg' => 'svg', Chris@0: ); Chris@0: Chris@0: protected $dom; Chris@0: Chris@0: protected $options; Chris@0: Chris@0: protected $encode = false; Chris@0: Chris@0: protected $rules; Chris@0: Chris@0: protected $out; Chris@0: Chris@0: /** Chris@0: * Create a traverser. Chris@0: * Chris@17: * @param \DOMNode|\DOMNodeList $dom The document or node to traverse. Chris@17: * @param resource $out A stream that allows writing. The traverser will output into this Chris@17: * stream. Chris@17: * @param array $options An array of options for the traverser as key/value pairs. These include: Chris@17: * - encode_entities: A bool to specify if full encding should happen for all named Chris@17: * charachter references. Defaults to false which escapes &'<>". Chris@17: * - output_rules: The path to the class handling the output rules. Chris@0: */ Chris@0: public function __construct($dom, $out, RulesInterface $rules, $options = array()) Chris@0: { Chris@0: $this->dom = $dom; Chris@0: $this->out = $out; Chris@0: $this->rules = $rules; Chris@0: $this->options = $options; Chris@0: Chris@0: $this->rules->setTraverser($this); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tell the traverser to walk the DOM. Chris@0: * Chris@17: * @return resource $out Returns the output stream. Chris@0: */ Chris@0: public function walk() Chris@0: { Chris@0: if ($this->dom instanceof \DOMDocument) { Chris@0: $this->rules->document($this->dom); Chris@0: } elseif ($this->dom instanceof \DOMDocumentFragment) { Chris@0: // Document fragments are a special case. Only the children need to Chris@0: // be serialized. Chris@0: if ($this->dom->hasChildNodes()) { Chris@0: $this->children($this->dom->childNodes); Chris@0: } Chris@0: } // If NodeList, loop Chris@0: elseif ($this->dom instanceof \DOMNodeList) { Chris@0: // If this is a NodeList of DOMDocuments this will not work. Chris@0: $this->children($this->dom); Chris@0: } // Else assume this is a DOMNode-like datastructure. Chris@0: else { Chris@0: $this->node($this->dom); Chris@0: } Chris@0: Chris@0: return $this->out; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Process a node in the DOM. Chris@0: * Chris@17: * @param mixed $node A node implementing \DOMNode. Chris@0: */ Chris@0: public function node($node) Chris@0: { Chris@0: // A listing of types is at http://php.net/manual/en/dom.constants.php Chris@0: switch ($node->nodeType) { Chris@0: case XML_ELEMENT_NODE: Chris@0: $this->rules->element($node); Chris@0: break; Chris@0: case XML_TEXT_NODE: Chris@0: $this->rules->text($node); Chris@0: break; Chris@0: case XML_CDATA_SECTION_NODE: Chris@0: $this->rules->cdata($node); Chris@0: break; Chris@0: case XML_PI_NODE: Chris@0: $this->rules->processorInstruction($node); Chris@0: break; Chris@0: case XML_COMMENT_NODE: Chris@0: $this->rules->comment($node); Chris@0: break; Chris@0: // Currently we don't support embedding DTDs. Chris@0: default: Chris@0: //print ''; Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Walk through all the nodes on a node list. Chris@0: * Chris@17: * @param \DOMNodeList $nl A list of child elements to walk through. Chris@0: */ Chris@0: public function children($nl) Chris@0: { Chris@0: foreach ($nl as $node) { Chris@0: $this->node($node); Chris@0: } Chris@0: } Chris@0: Chris@0: /** Chris@0: * Is an element local? Chris@0: * Chris@17: * @param mixed $ele An element that implement \DOMNode. Chris@0: * Chris@17: * @return bool true if local and false otherwise. Chris@0: */ Chris@0: public function isLocalElement($ele) Chris@0: { Chris@0: $uri = $ele->namespaceURI; Chris@0: if (empty($uri)) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: return isset(static::$local_ns[$uri]); Chris@0: } Chris@0: }