views:

195

answers:

1

I'm working on the code below to allow HTTP user agents that cannot perform XSL transformations to view the resources on my server. I'm mystified because the result of transformToXML is false, but the result of libxml_get_errors() is an empty array. As you can see, the code outputs the LibXSLT version ID and I'm getting the problem on WinVista with version 1.1.24. Is libxml_get_errors() not the right function to get the errors from the XSLTProcessor object?

If you're interested in the XML documents, you can get them from http://bobberinteractive.com/index.xhtml and .../stylesheets/layout.xsl


<?php
//redirect browsers that can handle the source files.
if (strpos ( $_SERVER ['HTTP_ACCEPT'], 'application/xhtml+xml' )) {
 header ( "HTTP/1.1 301 Moved Permanently" );
 header ( "Location: http://" . $_SERVER ['SERVER_NAME'] . "/index.xhtml" );
 header ( "Content-Type: text/text" );
 echo "\nYour browser is capable of processing the <a href='/index.xhtml'> site contents on its own.";
 die ();
}
//start by checking the template
$baseDir = dirname ( __FILE__ );
$xslDoc = new DOMDocument ();
if (! $xslDoc->load ( $baseDir . '/stylesheets/layout.xsl' )) {
 header ( "HTTP/1.1 500 Server Error" );
 header ( "Content-Type: text/plain" );
 echo "\n Can't load " . $baseDir . '/stylesheets/layout.xsl';
 die ();
}

//resolve the requested resource (browsers that need transformation will request the resource without the suffix)
$uri = $_SERVER ['REQUEST_URI'];
$len = strlen ( $uri );
if (1 >= $len || '/' == substr ( $uri, $len - 1 )) {
 $fileName = $baseDir . "/index.xhtml"; // use 'default' document if pathname ends in '/'
} else {
 $fileName = $baseDir . (1 load ( $fileName )) {
 header ( "HTTP/1.1 500 Server Error" );
 echo "\n Can't load " . $fileName;
 die ();
}
// now start the XSL template processing
$proc = new XSLTProcessor ();
$proc->importStylesheet ( $xslDoc );
$doc = $proc->transformToXML ( $xmlDoc );
if (false === $doc) {
 header ( "HTTP/1.1 500 Server Error" );
 header ( "Content-Type: text/plain" );
 echo "\n";
 // HERE is where it gets strange: the value of $doc is false and libxml_get_errors returns 0 entries.
 display_xml_errors ( libxml_get_errors() );
 die ();
}
header ( "Content-Type: text/html" );
echo "\n";
echo $doc;

function display_xml_errors($errors) {
 echo count ( $errors ) . " Error(s) from LibXSLT " . LIBXSLT_DOTTED_VERSION;
 for($i = 0; $i level) {
   case LIBXML_ERR_WARNING :
    $return .= "Warning $error->code: ";
    break;
   case LIBXML_ERR_ERROR :
    $return .= "Error $error->code: ";
    break;
   case LIBXML_ERR_FATAL :
    $return .= "Fatal Error $error->code: ";
    break;
  }

  $return .= trim ( $error->message ) . "\n  Line: $error->line" . "\n  Column: $error->column";

  if ($error->file) {
   $return .= "\n  File: $error->file";
  }

  echo "$return\n\n--------------------------------------------\n\n";
 }
}

+1  A: 

I'm getting several errors when loading your XML or executing your XSL. Upgrade your error_reporting level

error_reporting(E_ALL | E_STRICT);
// or
error_reporting(-1); // overzealous, but works

Got me:

PHP Warning:  DOMDocument::load(): Entity 'ndash' not defined in /tmp/index.xhtml, line: 8 in /tmp/test.php on line 4
PHP Warning:  XSLTProcessor::importStylesheet(): compilation error: file /tmp/layout.xsl line 59 element a in /tmp/test.php on line 10
PHP Warning:  XSLTProcessor::importStylesheet(): Attribute 'onclick': The content is expected to be a single text node when compiling an AVT. in /tmp/test.php on line 10
PHP Warning:  XSLTProcessor::importStylesheet(): compilation error: file /tmp/layout.xsl line 185 element a in /tmp/test.php on line 10
PHP Warning:  XSLTProcessor::importStylesheet(): Attribute 'onclick': The content is expected to be a single text node when compiling an AVT. in /tmp/test.php on line 10
PHP Warning:  XSLTProcessor::transformToXml(): No stylesheet associated to this object in /tmp/test.php on line 12
Josh Davis
Not overzealous, quite the reporting you'd want during development without having to worry about a newly invented error type.
Wrikken
I was referring to using -1 instead of the error constants.
Josh Davis
I was too: error constants sometimes (well, rarely) get added so max int -1 will always catch them all. E_ALL does not work as it supposed to IMHO. Time for an E_REALLY_ALL
Wrikken
That sounds like good advice. When I add ini_set("display_errors", "On"); error_reporting(E_ALL);to my file, there's nothing new in the output. I'll move these files to my workstation and see what I can get running from the command line.The error reports Josh posted apparently are caused by some failure in libXSLT/libXML to handle entities. (ndash is an entity defined by the document's DTD and the other error seems to be a result of a failure to handle an entity defined in the stylesheet's DOCTYPE.) After replacing the entities, I get an invalid document returned from transformToXML.
John