* @license PHP License * @package wb * @subpackage Markup */ WBClass::load('WBMarkup_Handler'); /** * Markup Scanner Handler: Xml2Xml * * Convert Wombat XML data to well formed XML * * @version 0.2.0 * @package wb * @subpackage Markup */ class WBMarkup_Handler_Xml2xml implements WBMarkup_Handler { /** * current depth * @var int */ protected $depth = 0; /** * content * @var string */ protected $content = ''; /** * document's md5 sum * @var string */ protected $md5; /** * document nodes * @var array */ protected $doc = array(); /** * list of running converters (WBMarkup_Converter) * @var array */ protected $con = array(); /** * handler on start beginning of scan * * * * @param string $content * @return bool usually true, false to stop the scanner */ public function onScanStart(&$content) { $this->con = array(); $this->depth = 0; $this->content =& $content; $this->md5 = md5($content); $this->doc = array(); $this->doc[0] = array( 'ns' => '', 'tag' => '', 'attributes' => array(), 'isEmpty' => false, 'cData' => array(), 'depth' => $this->depth ); // inform converter about document's md5 and content foreach (array_keys($this->con) as $con) { $this->con[$con]->preset($this, $content); } return true; } /** * handler on start element * * @param string $ns The used namespace, if set. otherwise null * @param string $tag the tag itself * @param array $attributes the attributes of the found element * @param bool $isEmpty true if it is a start- and closing-Element (e.g.
) * @return bool usually true, false to stop the scanner */ public function onStartElement($ns, $tag, $attributes, $isEmpty) { ++$this->depth; $this->doc[$this->depth] = array( 'ns' => $ns, 'tag' => $tag, 'attributes' => $attributes, 'isEmpty' => $isEmpty, 'cData' => array(), 'depth' => $this->depth ); return true; } /** * handler fo cData * * Simply add cDate to document * * @uses replaceUrlString() * @param string $cData character data * @return bool usually true, false to stop the scanner */ public function onCharacterData($cData) { // replace vertical tabs $cData = str_replace("\v", ' ', $cData); $cData = htmlentities($cData, ENT_NOQUOTES | ENT_XML1, "UTF-8"); $this->doc[$this->depth]['cData'][] = $cData; return true; } /** * handler for entities * * Add entities to document's cData * * @param string $entity the entity element, e.g. nbsp for   * @param boolean $isUnicode true = the element is a unicode string */ public function onEntityElement($entity, $isUnicode) { $cData = '&'; if ('nbsp' == $entity) { $entity = '160'; $isUnicode = true; } if( $isUnicode ) { $cData .= '#'; } $cData .= $entity . ';'; $this->doc[$this->depth]['cData'][] = $cData; return true; } /** * test handler on end element * * @param string $ns The used namespace, if set. otherwise null * @param string $tag the tag itself * @param bool $empty defines if the tag is empty * @return bool usually true, false to stop the scanner */ public function onEndElement($ns, $tag, $empty) { // serialize node if( !$this->depth ) { return true; } $node = array_pop($this->doc); --$this->depth; if( $this->depth < 0 ) { $this->depth = 0; } $this->doc[$this->depth]['cData'][] = $this->node2String($node); return true; } /** * called right after scan is complete * * @return bool usually true, false to stop the scanner */ public function onScanComplete() { $this->content = $this->node2String($this->doc[0]); return true; } /** * receive translated content string * * @return string */ public function getParsedContent() { return $this->content; } /** * serialize document node * * @param array $node * @return string serialized attributes */ protected function node2String($node) { $cData = implode('', $node['cData']); if (!$node['tag']) { return $cData; } $tag = ''; if ($node['ns']) { $tag .= $node['ns'] . ':'; } $tag .= $node['tag']; $element = '<' . $tag . $this->attributes2String($node['attributes']); if ($node['isEmpty']) { $element .= ' />'; return $element; } $element .= '>' . $cData . ''; return $element; } /** * serialize attribute list to HTML attribute string * * @param array $att attribute list * @return string serialized attributes */ protected function attributes2String($att) { if (empty($att)) { return ''; } $str = ''; foreach ($att as $k => $v) { $str .= ' ' . $k . '="' . $v . '"'; } return $str; } } ?>