当前位置: 首页 > 知识库问答 >
问题:

对Thymeleaf的XHTML基本支持?

戚均
2023-03-14

我正在尝试让Spring 4.1.9和Thymeleaf 2.1.5渲染XHTML Basic 1.1页面,它们具有以下序言:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
    "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

简单地在模板中使用它是行不通的,因为百里香叶不能识别doctype。

org . thyme leaf . exceptions . templateprocessingexception:使用public id "-//W3C//DTD XHTML Basic 1.1//EN "和SYSTEMID " http://www . w3 . org/TR/XHTML-Basic/XHTML-Basic 11 . DTD "请求了不支持的实体。确保相应的org . thyme leaf . doctype . resolution . idoctyperesolutionentry实现由您的方言提供(索引:1)

我浏览了百里香扩展文档和源代码,并以此为起点,定义了一种继承自SpringStandardDialect的新方言。通过反复试验,我找到了丢失的模块,从error下载并添加到我的项目的资源目录中:

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<IDocTypeResolutionEntry> getAdditionalDocTypeResolutionEntries() {
        final Set<IDocTypeResolutionEntry> docTypeResolutionEntries = new LinkedHashSet<IDocTypeResolutionEntry>();
        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;
    }
}

我配置自定义方言如下:

...
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/templates/" />
    <property name="suffix" value=".xhtml" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="templateMode" value="XHTML" />
    <property name="xhtmlTemplateModePatterns" value="*.xhtml" /> 
</bean>

<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
    <property name="additionalDialects">
        <set>
            <bean class="demo.XhtmlBasicDialect" />
        </set>
    </property>
</bean>

<bean id="xhtmlViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="contentType" value="application/xhtml+xml" />
</bean>
...

我的模板如下:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
    "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Demo</title>
        <link th:href="${'style' + '.css'}" rel="stylesheet" type="text/css"/>
    </head>
    <body>      
        <div>
            <p>Demo content</p>
        </div>
    </body>
</html>

乍一看,这似乎很好,只是产生的XHTML缺少XML头,并且有几个额外的属性添加到每个元素中。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">

<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">
    <head xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <title xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Demo</title>
        <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" />
    </head>
    <body xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve">      
        <div xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve">
            <p xmlns="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:space="preserve">Demo content</p>
        </div>
    </body>
</html>

这与XHTML Basic的可预置性不太匹配;首先,我想保留XML声明<code>

更重要的是,我不希望将< code > xmlns = " http://www . w3 . org/1999/XHTML " 、< code > xmlns:xsi = " http://www . w3 . org/2001/XML schema-instance " 和< code > XML:space = " preserve " 属性添加到每个元素中。还有一个< code > version = "-//W3C//DTD XHTML Basic 1.1//EN " 属性添加到< code >中

我做错了什么,我需要不同的配置,还是我从自定义方言中遗漏了什么?

共有1个答案

弓温书
2023-03-14

好吧,我没有“规范”证据表明XHTML Basic模板不能用Thymeleaf 2. x以您想要的方式处理,并且可能有一种方法需要足够的努力。但我确实看到了:

  • Thymeleaf 2.1中的XhtmlAndHtml5NValidatingSAXTemplateParser看起来可疑,并且在Thymeleaf 3.0中不再存在
  • 现在不推荐使用XHTMLTempateModePatterns
  • 以及 xhtmlTempteModePatterns
  • 2.1中的所有解析代码都在3.0中重写了

这一点,加上我自己努力让一些东西正常工作,让我相信Thymeleaf 2中的XHTML处理。X从未完全烘烤过。然而,它似乎在3.0中工作得很好,无需特别努力。只需配置ViewResolver如下所示:

<bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="characterEncoding" value="UTF-8"/>
    <property name="templateEngine">
        <bean class="org.thymeleaf.spring4.SpringTemplateEngine">
            <property name="enableSpringELCompiler" value="true"/>
            <property name="templateResolver">
                <bean class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
                    <property name="prefix" value="/WEB-INF/templates/"/>
                    <property name="suffix" value=".xhtml"/>
                    <property name="templateMode" value="XML"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

我在github上发布了一个完整的工作示例。

 类似资料:
  • 我有一个Java/SpringBoot服务,它使用Thymeleaf将来自其他位置的HTML和CSS片段组装成PDF文档。我注意到,我内联到文档中的CSS使用Flexbox属性:。然而,Thymeleaf似乎不遵守这些CSS规则。Thymeleaf是否支持Flexbox和CSS3功能?

  • 我试图将视图与结合使用。我有一个实体,拥有一组电子邮件,我想在Thymeleaf模板中访问这些电子邮件: 在用户中。斯卡拉 在一些模板中。html 问题是Spring表达式求值器(Thymeleaf将表达式求值任务委托给它)只理解Java集合类型,因此试图获取Scala列表的第一个元素()/>)失败,出现异常。 我试图深入SpEL源代码,找到一个可以添加Java到Scala转换的地方。似乎如果我可

  • 问题内容: 我正在这样写我的文档测试: 这对于Python 2.5、2.6和2.7版本可以正常工作,但对于Python 3则失败,并出现以下错误: 问题是,如果我这样编写我的doctest: 它们仅适用于Python3,而在Python2版本上无效。我的问题是如何使其跨版本兼容? 问题答案: 我在IPython中遇到了与doctests相同的问题。没有整洁的解决方案,但是我将所有前缀都包装在中,即

  • 我计划从JBOSS EAP迁移到支持旧版本Java如6或7的Wildfly版本。 我找不到与野生苍蝇和java的兼容性矩阵。 另外,有任何版本的野蝇支持solaris 5吗? wildfly 8是否支持旧的java和Solaris版本。 有人能给我指一下矩阵吗?在那里我可以找到wildfly的兼容性和需求。

  • 问题内容: 当前版本的Node.js是否有对Promise的本地支持? Node.js使用V8引擎。Chrome也使用此JavaScript引擎,而Chrome 32具有对Promise的本机支持。但是我似乎无法获得在Node.js中(本机)工作的承诺。 我已经在Chrome 32中尝试了以下代码,并且可以正常工作。 但是,当我在Node.js中尝试相同的代码时,我得到: 此代码来自出色的教程:

  • 问题内容: 这不会产生任何输出。怎么来的? 但是这些可以做到: 问题答案: 的默认模式是(iirc)POSIX正则表达式,并且是pcre。您可以传递给gnu grep,以获得类似perl的正则表达式,也可以使用代替。