【问题标题】:Using different 'select' for same template (avoiding repetition)对同一模板使用不同的“选择”(避免重复)
【发布时间】:2019-07-06 20:23:11
【问题描述】:

这是简化的问题:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml"
    version="2.0">

    <xsl:param name="foo" select="'test'"/> <!-- 'test' can also be empty '' or whatever -->

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

    <xsl:template match="/">
        <html>
            <head>
                <title>bar</title>
            </head>
            <body>
                <xsl:choose>

                    <xsl:when test="string-length($foo)=0">
                        <ol>
                            <xsl:for-each select="something/something2"> <!-- SEE THIS? -->
                                <li>
                                    <xsl:call-template name="generic" />
                                </li>
                            </xsl:for-each>
                        </ol>
                    </xsl:when>

                    <xsl:otherwise>
                        <ol>
                            <xsl:for-each select="something/something2[tmp = $foo"]> <!-- SO MUCH REPETITION!! -->
                                <li>
                                    <xsl:call-template name="generic" />
                                </li>
                            </xsl:for-each>
                        </ol>
                    </xsl:otherwise>

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

我认为这很简单:我怎样才能避免这种重复?我尝试使用xsl:if 设置xsl:variable,但后来我无法在if 之外使用该变量,因此它变得无用。

同样,我只想让&lt;ol&gt; 仅在&lt;xsl:if test="count($varYouMightFigureOut) &gt; 1"&gt; 时应用,否则,它只能是&lt;xsl:call-template name="generic" /&gt;,它自己被调用(for-each&lt;li&gt; 变得无关紧要,不应该' t 被显示)。再说一遍:一个简单的解决方案涉及大量重复,但我宁愿避免这样的事情。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: xml xslt xpath xhtml


    【解决方案1】:

    您可以通过完全接受 XSLT 的内在美来避免这种重复。
    使用模板功能,如下例所示:

    将中心模板简化为本质:

    <xsl:template match="/">
        <html>
            <head>
                <title>bar</title>
            </head>
            <body>
                <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>
    

    并添加两个子模板,在假设的根 &lt;root&gt; 元素上实现最后一个 IF 条件(其名称必须与 XML 根元素的名称相同)

    <xsl:template match="root">
       <xsl:call-template name="generic" />
    </xsl:template> 
    
    <xsl:template match="root[$varYouMightFigureOut > 1]">
       <ol>
           <xsl:apply-templates />
       </ol>
    </xsl:template> 
    

    然后将xsl:choose这两种可能性浓缩成这两个模板:

    <xsl:template match="something/something2[string-length($foo)=0]">
       <li>
           <xsl:call-template name="generic" />
       </li>
    </xsl:template> 
    
    <xsl:template match="something/something2[tmp = $foo]">
       <li>
           <xsl:call-template name="generic" />
       </li>
    </xsl:template> 
    

    (如有必要,您可以将参数添加到xsl:call-template)。

    并使用上述模板使用的占位符“通用”模板完成此操作:

    <xsl:template name="generic">
      <xsl:value-of select="normalize-space(.)" />
    </xsl:template> 
    

    此解决方案避免了所有不必要的重复,并利用了 XSLT 的强大功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-01
      • 1970-01-01
      • 2019-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-13
      • 2020-10-17
      相关资源
      最近更新 更多