XSLT 1.0中的条件<xsl:output>?</xsl:output>

时间:2009-03-11 10:29:09

标签: xslt xslt-1.0

我有一个产生的XSLT 1.0(2.0不是一个选项)样式表 XHTML。它可以根据参数生成完整的XHTML 有效的文档或仅用于<div>...</div>代码段 包含在网页中。

我的问题是在这两个中生成不同的XML声明 案例。对于独立页面,我需要:

<xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
       doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

对于<div>一个:

<xsl:output omit-xml-declaration="yes"/>

<xsl:output>无法包含<xsl:if>。它只能是<xsl:stylesheet>直接子项。

我看到的唯一解决方案是创建一个包含大部分模板的样式表,然后使用右侧<xsl:output>创建两个小“包装器”,它们将<xsl:import>主样式表。

我一直在寻找更好的主意,但显然没有。根据Andrew Hare和jelovirt的建议,我写了两个“驱动程序”,两个简单的样式表,它们调用了正确的<xsl:output>,然后是主样式表。以下是其中一个驱动程序,一个用于独立HTML:

<?xml version="1.0" encoding="us-ascii"?>
<!-- This file is intended to be used as the main stylesheet, it creates a 
 standalone Web page. 
-->
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

  <xsl:import href="traceroute2html.xsl"/>

  <xsl:param name="standalone" select="'true'"/>

  <xsl:output doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

</xsl:stylesheet>

3 个答案:

答案 0 :(得分:2)

我最近不得不采用的另一个选择是:

  1. 在所有情况下都省略XML声明。
  2. 有条件地,将声明输出为未转义的文字
  3. 如果您要输出到文件,这仅适用于XSLT 1.0和2.0 - 如果您需要在同一个传递中将输出处理为XML,这将无效,例如存储在变量中时。

    (请注意,XSLT 2.0扩展函数可以使用此输出并将其作为XML一次性处理,而XSLT 3.0具有内置函数来将输入字符串解析为XML。)

    示例摘录:

    <!-- Omit the XML declaration as the base case:
        we can conditionally output a declaration 
        as text, but we *cannot* apply conditions on
        this `omit-xml-declaration` attribute here.  -->
    <xsl:output method="xml" indent="no" 
        omit-xml-declaration="yes"
    />
    
    <!-- Root element match: evaluate different cases, output XML declaration,
        XHTML DOCTYPE, or something else, then process the rest of the input. -->
    <xsl:template match="/">
        <xsl:choose>
            <xsl:when test="'... some condition ...'">
                <xsl:text disable-output-escaping="yes">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</xsl:text>
            </xsl:when>
            <xsl:when test="'... some other condition ...'">
                <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <!-- ... some third kind of output ... -->
            </xsl:otherwise>
        </xsl:choose>
        <!-- Just process the rest -->
        <xsl:apply-templates/>
    </xsl:template>
    
    
    ... [ other code ] ...
    

答案 1 :(得分:1)

听起来你需要的是两种不同的样式表。如果可能的话,你应该创建两个单独的样式表,并从代码中动态调用你需要的样式表。

答案 2 :(得分:1)

在XSLT中,omit-xml-declaration的值必须是yesno,您不能在那里使用属性值模板。这适用于1.0和2.0。

doctype属性可以使用AVT,但问题是您不能省略该属性,只能输出一个空属性,这会导致输出具有空的doctype字符串。

抱歉,XSLT无法完成。您可以使用两个不同的样式表,也可以在调用XSLT处理器的代码中设置输出参数。