1
votes

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
Thanks for provding the documents. On a side note: Opera could process the index.xhtml, but your webserver sends a Content-Type: */* instead of application/xhtml+xml, so it doesn't get processed. Easy fix, lots of thanks from the small Opera community.Wrikken
@Wrikken: thanks for noting the mime-type problem. I was monkeying with the type mapping to see what effect I could get specifying Content-Type using the http-equiv head/meta element.John

1 Answers

2
votes

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