Set HTML5 doctype with XSLT

HtmlXsltDoctypeXhtml TransitionalXdv

Html Problem Overview


How would I cleanly set the doctype of a file to HTML5 <!DOCTYPE html> via XSLT (in this case with collective.xdv)

The following, which is the best my Google foo has been able to find:

<xsl:output
    method="html"
    doctype-public="XSLT-compat"
    omit-xml-declaration="yes"
    encoding="UTF-8"
    indent="yes" />

produces:

<!DOCTYPE html PUBLIC "XSLT-compat" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Html Solutions


Solution 1 - Html

I think this is currently only supported by writing the doctype out as text:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" encoding="utf-8" indent="yes" />

  <xsl:template match="/">
    <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html&gt;</xsl:text>
    <html>
    </html>
  </xsl:template>
  
</xsl:stylesheet>

This will produce the following output:

<!DOCTYPE html>
<html>
</html>

Solution 2 - Html

To use the simple HTML doctype <!DOCTYPE html>, you have to use the disable-output-escaping feature: <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>. However, disable-output-escaping is an optional feature in XSLT, so your XSLT engine or serialization pipeline might not support it.

For this reason, HTML5 provides an alternative doctype for compatibility with HTML5-unaware XSLT versions (i.e. all the currently existing versions of XSLT) and other systems that have the same problem. The alternative doctype is <!DOCTYPE html SYSTEM "about:legacy-compat">. To output this doctype, use the attribute doctype-system="about:legacy-compat" on the xsl:output element without using a doctype-public attribute at all.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="html" doctype-system="about:legacy-compat"/>
   ...
   <html>
   </html>
</xsl:stylesheet>

Solution 3 - Html

<xsl:output
     method="html"
     doctype-system="about:legacy-compat"
     encoding="UTF-8"
     indent="yes" />

this outputs

<!DOCTYPE html SYSTEM "about:legacy-compat">

this is modified as my fix to http://ukchill.com/technology/generating-html5-using-xslt/

Solution 4 - Html

With Saxon 9.4 you can use:

<xsl:output method="html" version="5.0" encoding="UTF-8" indent="yes" />

This generates:

<!DOCTYPE HTML>

Solution 5 - Html

Use doctype-system instead of doctype-public

Solution 6 - Html

You must use XHTML 1.0 Strict as the doctype if you want XHTML output consistent with HTML5, libxml2's xml serializer has a special output mode triggered by the XHTML 1.0 doctypes that ensures output is XHTML compatible, (e.g. <br /> rather than <br/>, <div></div> rather than <div/>). doctype-system="about:legacy-compat" does not trigger this compatibility mode

If you are happy with html output, then setting <xsl:output method="html"> should do the right thing. You can then set the doctype with <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>, though this will need plumbing in at the appropriate place as XDV does not support this yet.

In fact it seems <xsl:output method="html"/> does not really help either - this will result in <br/> being output as <br></br>.

Solution 7 - Html

This variation of Jirka Kosek's advice, via Advanced XDV theming on Plone.org seems to work for me in collective.xdv.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output
      doctype-public="HTML"
      doctype-system=""/>
</xsl:stylesheet>

Solution 8 - Html

This is a comment, but I do not have enough karma points to put it in the correct place. Sigh.

> I appreciate this is probably the correct, standards driven way to accomplish what I want (I've upvoted it as such). But the former isn't supported (my processor falls over) and the latter still results in "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" in my doctype. As @Jirka Kosek suggested, I think my XSLT processor might be broken.

No, your XSLT processor is not broken, it's just that XDV adds:

<xsl:output method="xml" indent="no" omit-xml-declaration="yes" media-type="text/html" encoding="utf-8" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

by default, so when you add a second <xsl:output doctype-system="about:legacy-compat"/> the previous doctype-public is not overwritten.

Note that XHTML 1.0 strict is listed as an obsolete permitted doctype string, so it is perfectly acceptable to use this doctype and still call it HTML5.

Solution 9 - Html

Sorry to only provide links but this was discussed among the WHATWG group but it's been many months since I've dealt with it. Here Ian Hickson and some XML experts discuss this:
http://lists.w3.org/Archives/Public/public-html/2009Jan/0640.html
http://markmail.org/message/64aykbbsfzlbidzl
and here is the actual issue number:
http://www.w3.org/html/wg/tracker/issues/54
and here's this discussion
http://www.contentwithstyle.co.uk/content/xslt-and-html-5-problems

Solution 10 - Html

Use this tag

http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output method="xml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="XSLT-compat" indent="yes"/>

Solution 11 - Html

The following code will work as a standalone template if saved as html5.xml:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="html5.xml"?>
<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
            >
<xsl:output method="xml" encoding="utf-8" version="" indent="yes" standalone="no" media-type="text/html" omit-xml-declaration="no" doctype-system="about:legacy-compat" />

<xsl:template match="xsl:stylesheet">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="/">
  <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    </head>
    <body>
      <xsl:text>hi</xsl:text>
    </body>
  </html>
</xsl:template>

</xsl:stylesheet>

References

Solution 12 - Html

that's what i use to generate a compatible html5 doctype (getting saxons html5 out, otherwise doing the legacy thing)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xsl:stylesheet
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns="http://www.w3.org/TR/REC-html40">

	<xsl:output
    	method="html"
    	version="5.0"
	    doctype-system="about:legacy-compat"
		encoding="UTF-8"
	    indent="yes" />

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJon HadleyView Question on Stackoverflow
Solution 1 - HtmlDirk VollmarView Answer on Stackoverflow
Solution 2 - HtmlhsivonenView Answer on Stackoverflow
Solution 3 - HtmlJim MichaelsView Answer on Stackoverflow
Solution 4 - HtmlstephanmeView Answer on Stackoverflow
Solution 5 - HtmlJirka KosekView Answer on Stackoverflow
Solution 6 - HtmlLaurence RoweView Answer on Stackoverflow
Solution 7 - HtmlJon HadleyView Answer on Stackoverflow
Solution 8 - HtmlLaurence RoweView Answer on Stackoverflow
Solution 9 - HtmlRobView Answer on Stackoverflow
Solution 10 - HtmlAnil Kumar GuptaView Answer on Stackoverflow
Solution 11 - HtmlPaul SweatteView Answer on Stackoverflow
Solution 12 - HtmlBananaAcidView Answer on Stackoverflow