quickerUBB UBB extension implementing syntax highlighting for [xml]-tags
HotScript @ RoŲnašn index for more scripts and extensions.
Run this script as an example.
<?
  
/**********************************************
  * quickerUbb XML-highlight extension (c)2003 RoŲnašn
  *          
  * This file contains an extension to the quickerUBB
  * parsing engine.
  *
  * To implement the xml functionality
  * you can do two things:
  * - add this file to your project and include it.
  * - copy the parse_xml and _parse_xml_* methods
  *   into the ubbParser class as is explained
  *   in quickerubb.php.
  *
  * quickerUbb can be found at
  * http://www.roonaan.nl/hotscripts
  *
  * Namespace functionality is not included as it is for the
  * moment still undocumented.
  *
  * As this extension, other extensions will not be
  * scripted directly into the quickerubb.php file, but
  * will come available as seperate classes. I recognize
  * this takes more effort to assemble all the functionality
  * you need, but I thought this was best, because most
  * extensions are scripted on specific request rather than
  * general needs.
  *
  * For Questions and comments: hotscripts@roonaan.nl
  * please add script name to your email subject.  *
  */
  
$start_time = !isset($start_time) ? explode(' 'microtime()) : $start_time;

include_once 
'quickerubb.php';

class 
ubbXmlParser extends ubbParser
{
  function 
parse_xml($tree)
  {
    
ob_start();
    
/* parsing options */
    
    
    /* parsing start; do not edit below this line */
    
$params $tree->getParameters();
    
$disptype 'tree';    
    if(isset(
$params['xml']))
      
$disptype $params['xml'];
    
$old_dt   $this->_parse_xml_display;
    
$old_crlf $this->_parse_xml_preserve_newlines;

    
$this->_parse_xml_var_level 0;
    
$this->_parse_xml_var_buffer '';
    
$this->_parse_xml_last_opened '';
    
$this->_parse_xml_display '';
    
$this->_parse_xml_preserve_newlines false;
    if(
strtolower($disptype)=='tree' || strtolower($disptype)=='ptree'$this->_parse_xml_display 'tree';
    if(
strtolower($disptype)=='pre'  || strtolower($disptype)=='ptree'$this->_parse_xml_preserve_newlines true;
    
$p xml_parser_create();
    
xml_set_object($p,$this);
    
xml_set_element_handler($p,'_parse_xml_open','_parse_xml_close');
    
xml_set_default_handler($p,'_parse_xml_default');
    
xml_set_character_data_handler($p,'_parse_xml_cdata');
    
xml_set_processing_instruction_handler($p'_parse_xml_pi');
    
$t $tree->ToText($this);
    
$t str_replace('&','&amp;',$t);
    
xml_parse($p,$t);
    if(
$c=xml_get_error_code($p))
    {
      
$b xml_get_current_byte_index($p);
      echo 
'<div><font color="990000">XML-tag error: </font><font color="000099">'.xml_error_string($c);
      echo 
' on line '.xml_get_current_line_number($p).' column '.xml_get_current_column_number($p).': "</font>'.htmlspecialchars(substr($t$b10)).'<font color="000099">"';
      echo 
'</font></div>';
    }
    
$t ob_get_contents();
    
ob_end_clean();
    
$this->_parse_xml_display $old_dt;
    
$this->_parse_xml_preserve_newlines $old_crlf;
    return 
$t;
  }
  
  var 
$_parse_xml_preserve_newlines false;
  var 
$_parse_xml_use_css false;
  var 
$_parse_xml_output_css_stylesheet false;
  var 
$_parse_xml_var_level;
  var 
$_parse_xml_last_opened;
  var 
$_parse_xml_display;
  var 
$_parse_xml_var_buffer;
  
  function 
_parse_xml_open($parser$tag$attribs)
  {
    
$this->_parse_xml_last_opened $tag;
    if(
$this->_parse_xml_display == 'tree') echo '<br />'.str_repeat('&nbsp;',2$this->_parse_xml_var_level);
    
$this->_parse_xml_var_level++;
    
$this->_parse_xml_output('&lt;','xml_anchor');
    
$this->_parse_xml_output($tag'xml_tag');
    
$attrs 0;
    foreach(
$attribs as $name => $value)
    {
      echo 
' ';
      
$this->_parse_xml_output($name'xml_attrib');
      
$this->_parse_xml_output('=','xml_anchor');
      
$this->_parse_xml_output('"','xml_anchor');
      
$this->_parse_xml_output(htmlspecialchars($value),'xml_content');
      
$this->_parse_xml_output('"','xml_anchor');
    }
    
$this->_parse_xml_output('&gt;','xml_anchor');
  }
  function 
_parse_xml_close($parser$tag)
  {
    
//$this->_parse_xml_var_buffer = '!!';
    
if(!empty($this->_parse_xml_var_buffer))
    {
      echo 
$this->_parse_xml_text_handle(htmlspecialchars($this->_parse_xml_var_buffer));
      
$this->_parse_xml_var_buffer '';
    }
    
$this->_parse_xml_var_level--;
    if(
$this->_parse_xml_display == 'tree' && $this->_parse_xml_last_opened != $tag) echo '<br />'.str_repeat('&nbsp;',2$this->_parse_xml_var_level);
    
$this->_parse_xml_output('&lt;','xml_anchor');
    
$this->_parse_xml_output('/''xml_tag');
    
$this->_parse_xml_output($tag'xml_tag');
    
$this->_parse_xml_output('&gt;','xml_anchor');
  }
  function 
_parse_xml_default($parser$data)
  {
    echo 
$this->_parse_xml_text_handle(htmlspecialchars($data));
  }
  
  function 
_parse_xml_cdata($parser$cdata)
  {
    
$this->_parse_xml_var_buffer .= $cdata;
    
//echo $this->_parse_xml_text_handle(htmlspecialchars($cdata));
  
}
  
  function 
_parse_xml_pi($parser$target$data)
  {
    if(
$this->_parse_xml_display == 'tree') echo '<br />'.str_repeat('&nbsp;',2$this->_parse_xml_var_level);
    
$this->_parse_xml_output('&lt;?','xml_anchor');
    
$this->_parse_xml_output($target'xml_tag');
    echo 
' ';
    
$this->_parse_xml_output(htmlspecialchars($data),'content');
    
$this->_parse_xml_output('?&gt;','xml_anchor');
  }  
  
  function 
_parse_xml_text_handle($data)
  {
    if(
$this->_parse_xml_preserve_newlines)
    {
      if(
strlen(trim($data)) > 0)
        
$data nl2br(trim($data));
      else
        
$data '';
    }
    else
      
$data trim($data);
    return 
$data;
  }
  
  function 
_parse_xml_output($data$type)
  {
    if(
$this->_parse_xml_use_css)
    {
      echo 
'<span class="'.$type.'">'.$data.'</span>';
    }
    else
    {
      switch(
$type)
      {
       case 
'xml_anchor':
        echo 
'<font color="0000FF">'.$data.'</font>';
        break;
       case 
'xml_tag':
        echo 
'<font color="990000">'.$data.'</font>';
        break;
       case 
'xml_content':
        echo  
'<font color="000000">'.$data.'</font>';
        break;
       case 
'xml_attrib':
        echo  
'<font color="990000">'.$data.'</font>';
        break;
       default:
        echo 
$data;
      }
    }
  }
  
}

/** Testcenter **/
$self $_SERVER['PHP_SELF'];
$file str_replace('\\','/',__FILE__);
$self substr($selfstrrpos($self'/')+1);
$file substr($filestrrpos($file'/')+1);
if(
$self==$file)
{
  
$parser = new ubbXmlParser();
  
$text '
  [b]XML-Tag testing[/b]
  [xml]
  <test:topic>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html>
     <b>Parsed data</b>
    </html>
    <ubb>
     [b]Parsed data
     over multiple lines[/b]
    </ubb>
   </post>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html test="&nbsp;">
     <b>&nbsp;</b>
    </html>
    <ubb>
     [b]&nbsp;[/b]
    </ubb>
   </post>
  <?woei hack="&lt;script&gt;" woei?'
.'>
  </test:topic>  
  [/xml]
  
  [i]Seems to be quite all-right.[/i]
  
  [b]Force Tree-like output[/b]
  [XML=tree]
  <test:topic>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html>
     <b>Parsed data</b>
    </html>
    <ubb>
     [b]Parsed data
     over multiple lines[/b]
    </ubb>
   </post>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html test="&nbsp;">
     <b>&nbsp;</b>
    </html>
    <ubb>
     [b]&nbsp;[/b]
    </ubb>
   </post>
  <?woei hack="&lt;script&gt;" woei?'
.'>
  </test:topic>  
  [/xml]

  [b]Preserve newlines[/b]

  [xml=pre]
  <test:topic>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html>
     <b>Parsed data</b>
    </html>
    <ubb>
     [b]Parsed data
     over multiple lines[/b]
    </ubb>
   </post>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html test="&nbsp;">
     <b>&nbsp;</b>
    </html>
    <ubb>
     [b]&nbsp;[/b]
    </ubb>
   </post>
  <?woei hack="&lt;script&gt;" woei?'
.'>
  </test:topic>  
  [/xml]

  [b]Preserve newlines in treeview[/b]

  [xml=ptree]
  <test:topic>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html>
     <b>Parsed data</b>
    </html>
    <ubb>
     [b]Parsed data
     over multiple lines[/b]
    </ubb>
   </post>
   <post>
    <date>2003-10-16</date>
    <user id="17153">Roonaan</user>
    <html test="&nbsp;">
     <b>&nbsp;</b>
    </html>
    <ubb>
     [b]&nbsp;[/b]
    </ubb>
   </post>
  <?woei hack="&lt;script&gt;" woei?'
.'>
  </test:topic>  
  [/xml]
  '
;
  echo 
$parser->parse($text);
}




$end_time explode(' 'microtime());
if(
$self==$file) echo '<hr /><div><small>Generation in: '.($end_time[0] + $end_time[1] - $start_time[0] - $start_time[1]).' secs</small></div>';