I am trying to generate valid HTML 5 output using XSL transformer in PHP and I am having difficulty doing so. Here is the sample PHP code:
<?php
$xml_source = '<?xml version="1.0" encoding="utf-8"?><content/>';
$xsl_source = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="utf-8" />
<xsl:template match="content">
<xsl:text disable-output-escaping="yes"><!DOCTYPE html> </xsl:text>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
<div style="color: green"></div>
This text should be black
<br/>
This black text is on next line
</body>
</html>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
EOD;
$xml = new DomDocument;
$xml->LoadXML($xml_source);
$xsl = new DomDocument;
$xsl->loadXML($xsl_source);
$xslt = new XSLTProcessor;
$xslt->importStyleSheet( $xsl );
echo $xslt->transformToXML( $xml );
When <xsl:output method="html"
it generates
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
<div style="color: green"></div>
This text should be black
<br></br>
This black text is on next line
</body>
</html>
<br></br>
gets interpreted into TWO breaks
When <xsl:output method="xml"
it generates
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<body>
<div style="color: green" />
This text should be black
<br />
This black text is on next line
</body>
</html>
The <div />
is self closing and that gets interpreted as just an opening <div>
and the text is green.
I need your advice on how to proceed. Is there some undocumented option in PHP XSL processor to make only some tags self-closing. Is there an alternative to built in XSLT processor?
I found a workaround. Since XHTML output is not available in XSLT 1.0 do following:
First, keep
xsl:output
asxml
.Second, force certain tags to render with separate closing tag by inserting something in the middle. For example, add
 
or<xsl:comment/>
in empty tags that suppose to have closing tag. like so<div style="color: green" ><xsl:comment/></div>
or<script src="http://asdfasdf"> </script>
. If you are converting XHTML source in XSL then do similar thing, but of course use<!---->
instead ofxsl:comment
Third, make sure not to remove empty comments and spaces from tags with your XSL templates. In all my stylesheets I include something like this.
This has worked very well for me so far.
HTML does not have self-closing tags. Primarily because HTML is not XML.
<br></br>
gets interpretted as 2 breaks, as a<br>
tag has no closing tag, which is why it tries to render it as two breaks.If you can render it as XHTML with the correct DOCTYPE, or try another approach.