【问题标题】:Dynamic doctype in XSLT transform (correct use of result-document instruction)XSLT 转换中的动态文档类型(正确使用结果文档指令)
【发布时间】:2011-05-15 14:07:38
【问题描述】:

我正在使用 XSLT,需要根据参数在转换后的输出中动态生成 doctype。 我听说这不能使用 XSLT 1.0 来完成,但可以使用 2.0 版,使用 result-document 标记。

到目前为止,从this问题中的答案来看,我有这样的事情:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" indent="yes"/>
    <xsl:param name="doctype.system" select="'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'" />
    <xsl:param name="doctype.public" select="'-//W3C//DTD XHTML 1.0 Strict//EN'" />
    <xsl:template match="/">
    <xsl:result-document doctype-public="{$doctype.public}" doctype-system="{$doctype.system}" method="html">
       <html>
          <head>
            <xsl:apply-templates select="report/head/node()"/>
          </head>
          <body>
             <!-- ommitted for brevity -->
          </body>
       </html>
    </xsl:result-document>
    </xsl:template>
    </xsl:stylesheet>

上面的问题是没有生成输出!

如果我从上面删除 results-document 标记,我的转换将被应用并输出一个文档,正如预期的那样。

有什么线索吗?我是否正确使用了结果文档标签?


更新:作为对某些 cmets 的回应,这里有一个可以工作的小版本,一个不工作的小版本(省略了结果文档指令的参数化)

这有效(没有结果文档):

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/> 
<xsl:template match="/">
   <html>
      <head>

      </head>
      <body>

   </body>
   </html>   
</xsl:template>
</xsl:stylesheet>

输出:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body></body>
</html>

但这不会产生任何输出:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/> 
<xsl:template match="/">
<xsl:result-document doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" method="html">
   <html>
      <head>

      </head>
      <body>

   </body>
   </html>
</xsl:result-document>   
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 您的 XSLT 处理器是什么? XSLT 版本?什么意思是“没有生成输出?文档类型不在结果文档中?结果文档是空的?或者根本没有生成结果文档?xsl:result-document 是 XSLT 2.0 所以确保你的引擎支持它,否则你的样式表不会编译。
  • 你有一个额外的&lt;/head&gt; 结束标签——你能发布一个实际工作并重现你的问题的最小示例吗?
  • 顺便说一句,一旦我删除了多余的结束标签,你的代码在撒克逊人看来对我来说工作得很好;传入“hello”和“test”的参数,得到:&lt;!DOCTYPE html PUBLIC "test" "hello"&gt;.
  • @Joel 我对 Xalan 了解不多,但我很快read 关于它的一切似乎都表明它是一个 XSLT 1.0 处理器。它甚至可以处理 XSLT 2.0 文档吗?
  • @Joel:Xalan 仅支持 XSLT 1.0 afaik,因此如果您不更改为兼容 XSLT 2.0 的处理器,那么使用 xsl:result-document 会很不走运。

标签: xslt xslt-2.0


【解决方案1】:

您还发现,Xalan 仅支持 XSLT 1.0,但如果您已更改为 Saxon 9,则可以轻松实现您想要的。

此外,您可以使用名称定义xsl:output,并将其用作xsl:result-document 中的格式,而不是使用您的文档类型设置来定义参数:

<xsl:output name="my-xhtml-output" method="xml" encoding="UTF-8" indent="yes"
  doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

然后在您的xsl:result-document 中使用此输出格式:

<xsl:result-document href="{$filename}" format="my-xhtml-output">
  ...
</xsl:result-document>

Imo,如果你有很多不同的输出格式,这可以更容易地维护它们。

【讨论】:

    【解决方案2】:

    当您使用 XSLT 1.0 引擎时,您必须使用 xsl:text 创建动态 DOCTYPE:

    <?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" indent="yes" />
    
      <xsl:param name="doctype.system" select="'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'" />
      <xsl:param name="doctype.public" select="'-//W3C//DTD XHTML 1.0 Strict//EN'" />
    
        <xsl:template match="/">
          <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html PUBLIC "</xsl:text>
          <xsl:value-of select="$doctype.public" />
          <xsl:text disable-output-escaping='yes'>" "</xsl:text>
          <xsl:value-of select="$doctype.system" />
          <xsl:text disable-output-escaping='yes'>"></xsl:text>
    
          <!-- further processing here -->
          <html>
    
          </html>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 感谢您的建议,根据问题中的 cmets,建议的替代解决方案是确保我使用的是符合 XSLT 2.0 的引擎。我改用撒克逊,效果很好。无论如何+1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2011-03-24
    • 2012-03-11
    相关资源
    最近更新 更多