title: XHTML Basic support for Thymeleaf?
body: <p>I'm trying to get Spring 4.1.9 and Thymeleaf 2.1.5 to render XHTML Basic 1.1 pages, which have the following preamble:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
      "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
  </code></pre>
  
  <p>Simply using this in a template doesn't work, as Thymeleaf doesn't recognize the doctype.</p>
  
  <blockquote>
    <p>org.thymeleaf.exceptions.TemplateProcessingException: Unsupported entity requested with PUBLICID "-//W3C//DTD XHTML Basic 1.1//EN" and SYSTEMID "<a href="http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd" rel="noreferrer">http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd</a>". Make sure a corresponding org.thymeleaf.doctype.resolution.IDocTypeResolutionEntry implementation is provided by you dialect (index:1)</p>
  </blockquote>
  
  <hr>
  
  <h1>Setup</h1>
  
  <p>I went through the Thymeleaf <a href="http://www.thymeleaf.org/doc/tutorials/2.1/extendingthymeleaf.html" rel="noreferrer">extension documentation</a> and <a href="https://github.com/thymeleaf" rel="noreferrer">source code</a> and using that as a starting point, defined a new dialect inheriting from SpringStandardDialect. I figured out the missing modules through trial and error, downloading them from w3.org and adding them to the resources directory of my project:</p>
  
  <h3>XhtmlBasicDialect.java</h3>
  
  <pre class="lang-java prettyprint-override"><code>import java.util.LinkedHashSet;
  import java.util.Set;
  
  import org.thymeleaf.doctype.DocTypeIdentifier;
  import org.thymeleaf.doctype.resolution.ClassLoaderDocTypeResolutionEntry;
  import org.thymeleaf.doctype.resolution.IDocTypeResolutionEntry;
  import org.thymeleaf.spring4.dialect.SpringStandardDialect;
  
  public class XhtmlBasicDialect extends SpringStandardDialect {
      private static final String DTD_STANDARD_PATH = "org/thymeleaf/dtd/standard/";
  
      private static final DocTypeIdentifier XHTML_BASIC_11_PUBLICID = DocTypeIdentifier.forValue("-//W3C//DTD XHTML Basic 1.1//EN");
      private static final DocTypeIdentifier XHTML_BASIC_11_SYSTEMID = DocTypeIdentifier.forValue("http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd");
      private static final DocTypeIdentifier ENTITIES_XHTML_BASIC_11_DOCUMENT_MODEL_1_PUBLICID = DocTypeIdentifier.forValue("-//W3C//ENTITIES XHTML Basic 1.1 Document Model 1.0//EN");
      private static final DocTypeIdentifier ELEMENTS_XHTML_BASIC_TABLES_1_PUBLICID = DocTypeIdentifier.forValue("-//W3C//ELEMENTS XHTML Basic Tables 1.0//EN");
      private static final DocTypeIdentifier ELEMENTS_XHTML_INPUTMODE_1_PUBLICID = DocTypeIdentifier.forValue("-//W3C//ELEMENTS XHTML Inputmode 1.0//EN");
      private static final DocTypeIdentifier ELEMENTS_XHTML_TARGET_1_PUBLICID = DocTypeIdentifier.forValue("-//W3C//ELEMENTS XHTML Target 1.0//EN");
      private static final IDocTypeResolutionEntry XHTML_BASIC_STRICT_DOC_TYPE_RESOLUTION_ENTRY = new ClassLoaderDocTypeResolutionEntry(XHTML_BASIC_11_PUBLICID, XHTML_BASIC_11_SYSTEMID, DTD_STANDARD_PATH + "xhtml-basic11.dtd");
      private static final IDocTypeResolutionEntry ENTITIES_XHTML_BASIC_11_DOCUMENT_MODEL_1_DOC_TYPE_RESOLUTION_ENTRY = new ClassLoaderDocTypeResolutionEntry(ENTITIES_XHTML_BASIC_11_DOCUMENT_MODEL_1_PUBLICID, DocTypeIdentifier.ANY, DTD_STANDARD_PATH + "xhtml-basic11-model-1.mod");
      private static final IDocTypeResolutionEntry ELEMENTS_XHTML_BASIC_TABLES_1_DOC_TYPE_RESOLUTION_ENTRY = new ClassLoaderDocTypeResolutionEntry(ELEMENTS_XHTML_BASIC_TABLES_1_PUBLICID, DocTypeIdentifier.ANY, DTD_STANDARD_PATH + "xhtml-basic-table-1.mod");
      private static final IDocTypeResolutionEntry ELEMENTS_XHTML_INPUTMODE_1_DOC_TYPE_RESOLUTION_ENTRY = new ClassLoaderDocTypeResolutionEntry(ELEMENTS_XHTML_INPUTMODE_1_PUBLICID, DocTypeIdentifier.ANY, DTD_STANDARD_PATH + "xhtml-inputmode-1.mod");
      private static final IDocTypeResolutionEntry ELEMENTS_XHTML_TARGET_1_DOC_TYPE_RESOLUTION_ENTRY = new ClassLoaderDocTypeResolutionEntry(ELEMENTS_XHTML_TARGET_1_PUBLICID, DocTypeIdentifier.ANY, DTD_STANDARD_PATH + "xhtml-target-1.mod");
  
      @Override
      protected Set&lt;IDocTypeResolutionEntry&gt; getAdditionalDocTypeResolutionEntries() {
          final Set&lt;IDocTypeResolutionEntry&gt; docTypeResolutionEntries = new LinkedHashSet&lt;IDocTypeResolutionEntry&gt;();
          docTypeResolutionEntries.add(XHTML_BASIC_STRICT_DOC_TYPE_RESOLUTION_ENTRY);
          docTypeResolutionEntries.add(ENTITIES_XHTML_BASIC_11_DOCUMENT_MODEL_1_DOC_TYPE_RESOLUTION_ENTRY);
          docTypeResolutionEntries.add(ELEMENTS_XHTML_BASIC_TABLES_1_DOC_TYPE_RESOLUTION_ENTRY);
          docTypeResolutionEntries.add(ELEMENTS_XHTML_INPUTMODE_1_DOC_TYPE_RESOLUTION_ENTRY);
          docTypeResolutionEntries.add(ELEMENTS_XHTML_TARGET_1_DOC_TYPE_RESOLUTION_ENTRY);
          return docTypeResolutionEntries;
      }
  }
  </code></pre>
  
  <p>I configure the custom dialect as follows:</p>
  
  <h3>mvc-config.xml</h3>
  
  <pre class="lang-xml prettyprint-override"><code>...
  &lt;bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"&gt;
      &lt;property name="prefix" value="/WEB-INF/templates/" /&gt;
      &lt;property name="suffix" value=".xhtml" /&gt;
      &lt;property name="characterEncoding" value="UTF-8" /&gt;
      &lt;property name="templateMode" value="XHTML" /&gt;
      &lt;property name="xhtmlTemplateModePatterns" value="*.xhtml" /&gt; 
  &lt;/bean&gt;
  
  &lt;bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine"&gt;
      &lt;property name="templateResolver" ref="templateResolver" /&gt;
      &lt;property name="additionalDialects"&gt;
          &lt;set&gt;
              &lt;bean class="demo.XhtmlBasicDialect" /&gt;
          &lt;/set&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="xhtmlViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver"&gt;
      &lt;property name="templateEngine" ref="templateEngine" /&gt;
      &lt;property name="characterEncoding" value="UTF-8" /&gt;
      &lt;property name="contentType" value="application/xhtml+xml" /&gt;
  &lt;/bean&gt;
  ...
  </code></pre>
  
  <p>My template is as follows:</p>
  
  <h3>DemoTemplate.xhtml</h3>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
      "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:th="http://www.thymeleaf.org"&gt;
      &lt;head&gt;
          &lt;title&gt;Demo&lt;/title&gt;
          &lt;link th:href="${'style' + '.css'}" rel="stylesheet" type="text/css"/&gt;
      &lt;/head&gt;
      &lt;body&gt;      
          &lt;div&gt;
              &lt;p&gt;Demo content&lt;/p&gt;
          &lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <hr>
  
  <h1>The Problem</h1>
  
  <p>At first glance, this seems to render fine, except that the resulting XHTML is missing the XML header, and has several extra attributes that are added to every element.</p>
  
  <h3>Rendered output:</h3>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"&gt;
  
  &lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="-//W3C//DTD XHTML Basic 1.1//EN"&gt;
      &lt;head xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
          &lt;title xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;Demo&lt;/title&gt;
          &lt;link rel="stylesheet" type="text/css" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve" href="style.css" /&gt;
      &lt;/head&gt;
      &lt;body xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve"&gt;      
          &lt;div xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve"&gt;
              &lt;p xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve"&gt;Demo content&lt;/p&gt;
          &lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>This doesn't quite match the XHTML Basic preamable; for one, I would like to keep XML declaration <code>&lt;?xml version="1.0" encoding="utf-8"?&gt;</code></p>
  
  <p>More importantly, I do not want the <code>xmlns="http://www.w3.org/1999/xhtml"</code>, <code>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</code>, and  <code>xml:space="preserve"</code> attributes to be added to just about every element. There's also an <code>version="-//W3C//DTD XHTML Basic 1.1//EN"</code> attribute added to the <code>&lt;html&gt;</code> element.</p>
  
  <p>Am I doing something wrong, do I need to configure something differently, or am I missing something from the custom dialect? </p>