Catching XML Error Messages With PHP 5.0

Intro

PHP 5.0 has a not so perfect implementation for throwing XML Parse Error Messages. It just uses the standard PHP error system, which makes it not that easy to catch (and display nicer warnings) within a PHP script. But as you can set your own error handler, there's a not-so-nice, but not too complicated solution to this.

The XML error system will most certainly be overhauled in PHP 5.1 with a much nicer way to catch those messages.

Code for XML Errors

The example is done with exceptions, as we're using them in the Popoon framework. You can of course implement it without exceptions.

What we actually do is to try to reparse the XML document, but first with setting the errorhandler to our own error method. As this will most certainly fail, the custom errorhandler will catch the errors und put them into the property userInfo. This property can then be accessed in the catch part of the code. After $dom->load() we then reset the error handler to the old value (restore_error_handler() takes automatically care of that)

class XMLParseErrorException extends Exception {
{panel}
    
    public function __construct($filename) {
        set_error_handler(array($this,"errorHandler"));
        $dom = new DomDocument();
        $dom->load($filename);
        restore_error_handler();
        $this->message = "XML Parse Error in $filename";
        parent::__construct();
    }
    
    public function errorHandler($errno, $errstr, $errfile, $errline) {
        $pos = strpos($errstr,"]:") ;
        if ($pos) {
            $errstr = substr($errstr,$pos+ 2);
        }
        $this->userInfo .="$errstr<br />\n";
    }
{panel}
}

and then your code could look like this.

$dom = new DomDocument();
try {
{panel}
  if (! $dom->load($xmlfile)) {
    throw new XMLParseErrorException($xmlfile);
  }
{panel}
} catch (Exception $e) {
{panel}
  print $e->getMessage();
  print " in ".$e->getFile(). " on line " .$e->getLine();
  print "<br/> \n";
  print $e->userInfo;
{panel}
}

Code for XSLT Errors

The same is theoretically possible for XSLT errors, unfortunately the error handler is not set in ext/xsl, therefore you need to patch PHP 5.0.0 (should hopefully be fixed in 5.0.1). The patch can be found here : http://svn.liip.ch/repos/public/misc/dompatches/xslt-error-handler.patch

The Exception looks similar to above.

class XSLTParseErrorException extends Exception {
{panel}
    
    public function __construct($filename) {
        $dom = new DomDocument();
        $xsl = new DomDocument();
        $dom->load($filename);
        $xsl->load($filename);
        set_error_handler(array($this,"errorHandler"));
        $proc = new XSLTProcessor();
        $proc->importStyleSheet($xsl);
        $proc->transformToDoc($dom);
        restore_error_handler();
        $this->message = "XSLT Error in $filename";
        parent::__construct();
        
    }
    
    public function errorHandler($errno, $errstr, $errfile, $errline) 
    {
        $pos = strpos($errstr,"]:") ;
        if ($pos) {
            $errstr = substr($errstr,$pos+ 2);
        }
        $this->userInfo .="$errstr<br />\n";
    }
    
{panel}
}

The actual code:

$dom = new DomDocument();
$xsl = new DomDocument();
$dom->load($xmlfile);
$xsl->load($xslfile);
$proc = new XSLTProcessor();
$proc->importStyleSheet($xsl);
try {
{panel}
  if (! $output = $proc->transformToDoc($xml)) {
    throw newXSLTParseErrorException($xslfile);
  }
{panel}
} catch (Exception $e) {
{panel}
   print $e->getMessage();
  print " in ".$e->getFile(). " on line " .$e->getLine();
  print "<br/> \n";
  print $e->userInfo;
{panel}
}

Validation errors

The same approach should work for validation errors. Implementation is left to the reader

Missing functionality

  • It only handles XML/XSL from files, if it's a string (to be used with $dom->loadXML()), we'd have to alter the Exception code slightly.
  • One could show the errors in a better context (showing the surrounding lines of the XML), furthermore the XSLT Errors do not report the linenumbers. I don't know, if this is fixable (in the extension...)</pre>

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.
These projects are supported by Liip AG