当从 XHTML 转换为 (X)HTML 时,从处理器的角度来看,您可能希望首先避免由 doctype 引起的解析阶段的外部解析,因为它可能是运行时错误的来源。
在这种情况下,您应该查看您的处理器是否支持禁用该选项的任何选项,或者您可能需要直接从输入文档中删除 doctype 声明。
例如,在 msxsl 中,您可以使用 xe 选项来禁用外部文档类型解析:
> msxsl test_i.xml test_t.xsl -o test_o.xml -xe
从 XSLT 1.0 的角度来看,您的 xhtml 只是具有特定名称空间的 XML 文档。例如:
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title></title>
</head>
<body>
<p>Foo</p>
</body>
</html>
要能够将其转换为其他 XHTML 文档,您的 XSLT 必须:
- 声明正确的默认命名空间和前缀
- 声明正确的输出和文档类型
您将使用定义的前缀访问输入文档中的元素。例如,这个转换只是在输入文档中添加一个标题:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="x">
<xsl:output method="html" indent="yes"
doctype-public="-//W3C//DTD XHTML 1.1//EN"
doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="x:body">
<xsl:copy>
<h1>Foo Title</h1>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意:
- 命名空间前缀
xmlns:x="http://www.w3.org/1999/xhtml"的声明允许您正确选择输入文档中符合xhtml命名空间的元素。
- 默认命名空间
xmlns="http://www.w3.org/1999/html" 的声明可防止在输出文档中生成不需要的空命名空间 xmlns=""。
-
exclude-result-prefixes 的使用允许您在 XSLT 中明确声明的输出文档元素中排除 xhtml 命名空间的声明。
从 XSLT 2.0 的角度来看,它确实非常简单。您可以声明 XPath 默认命名空间,从而摆脱前缀。样式表声明将是:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xpath-default-namespace="http://www.w3.org/1999/xhtml">