HTML 5 with PHP XSL transformer

2019-08-08 16:21发布

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">&lt;!DOCTYPE html&gt;&#10;</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?

2条回答
我欲成王,谁敢阻挡
2楼-- · 2019-08-08 17:00

I found a workaround. Since XHTML output is not available in XSLT 1.0 do following:

First, keep xsl:output as xml.

Second, force certain tags to render with separate closing tag by inserting something in the middle. For example, add &#160; 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">&#160;</script>. If you are converting XHTML source in XSL then do similar thing, but of course use <!----> instead of xsl: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.

    <xsl:template match="comment()|processing-instruction()">
      <xsl:copy>
        <xsl:apply-templates />
      </xsl:copy>
    </xsl:template>

This has worked very well for me so far.

查看更多
地球回转人心会变
3楼-- · 2019-08-08 17:11

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.

查看更多
登录 后发表回答