XSLT变量属性集

时间:2017-10-20 10:10:01

标签: xslt

我有一个与xsl:use-attribute-sets相关的问题。 我想拥有具有可变属性集的元素。 e.g:

<fo:block xsl:use-attribute-sets="$variable">
</block>

这种方法不起作用。 我试图找到一个解决方法并得出结论,可以通过for-each添加属性集的属性。 e.g:

<fo:block>
    <xsl:variable name="attributeSets" select="document('./document.xsl')//xsl:attribute-set"/>
    <xsl:for-each select="$attributeSets[@name=$attributeSetName]/xsl:attribute">
        <xsl:attribute name="@name" select="."/>
    </xsl:for-each>
</fo:block>

这种方法允许我将属性添加到元素中。问题是,如果属性包含像choose这样的xsl元素,则处理不当。

是否可以像这样评估xslt代码?

属性集看起来像这样:

<xsl:attribute-set name="test">
    <xsl:attribute name="font-size">
        <xsl:choose>
            <xsl:when test="condition">40pt</xsl:when>
            <xsl:otherwise>20pt</xsl:otherwise>
        </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="font-weight">bold</xsl:attribute>
    <xsl:attribute name="text-align">right</xsl:attribute>
</xsl:attribute-set>

输出结果为:

<fo:block font-size="40pt20pt" font-weight="bold" text-align="right"/>

1 个答案:

答案 0 :(得分:1)

  

我有一个与xsl:use-attribute-sets相关的问题。我希望有   元素,具有可变属性集。 [...]   这种方法不起作用。

不会。变量引用仅在表达式中有意义。某些XSL属性的值被定义为被解释为表达式,并且表达式可以在定义为属性值模板的属性值内发生,但是不会将xsl:use-attribute-sets属性的使用定义为属于这些类别中的任何一个

  

我试图找到一个解决方法并得出结论,它是   可以通过a添加属性集的属性   的for-each。 e.g:

<fo:block>
    <xsl:variable name="attributeSets" select="document('./document.xsl')//xsl:attribute-set"/>
    <xsl:for-each select="$attributeSets[@name=$attributeSetName]/xsl:attribute">
        <xsl:attribute name="@name" select="."/>
    </xsl:for-each>
</fo:block>
     

这种方法允许我将属性添加到元素中。

您正在阅读样式表文档作为附加输入文档,并将其转换为发出&lt; xsl:attribute&gt;元素到结果树中。它既聪明又可怕。

  

在   问题是,如果属性包含像choose这样的xsl元素,   它没有得到妥善处理。

如果通过“正确”,我猜你的意思是如果在xsl:use-attribute-sets属性中按名称(显式)指定属性集,将处理属性声明的方式。实际上,它不会那样处理。您正在使用样式表作为附加输入文档。这很好,因为XSL用XML表示,但输入文档没有XSL语义。

  

是否可以像这样评估xslt代码?

XSL具有从外部文件获取样式表部分的机制,但不能根据XSL语义处理随机节点集。也许有一个实现提供了这样的功能作为扩展,但我没有具体的知识。

除了您发现的解决方法之外,还有其他一些解决方法,其中一些应该提供您想要的XSLT语义。例如:

  • 使用模式或模板名称而不是计算变量值来选择属性集的组合:

    <xsl:template name="foo-bar-block">
      <fo:block xsl:use-attribute-sets="foo bar"/>
    </xsl:template>
    

您仍然无法动态计算模板名称或模式,但您可以动态选择要调用或应用的模板。

  • 使用模板代替属性集。 (可选)创建一个或多个主属性模板,以选择在任何给定情况下使用哪些伪属性集模板:

    <xsl:template name="variable-size-attributes">
      <xsl:attribute name="font-size">
        <xsl:choose>
          <xsl:when test="condition">40pt</xsl:when>
          <xsl:otherwise>20pt</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:template>
    
    <xsl:template name="font-style-attributes">
      <xsl:attribute name="font-weight">bold</xsl:attribute>
      <xsl:attribute name="text-align">right</xsl:attribute>
    </xsl:template>
    
    <xsl:template match="*">
      <fo:block>
        <!-- possibly a conditional here ... -->
        <xsl:call-template name="variable-size-attributes"/>
        <!-- possibly a conditional here ... -->
        <xsl:call-template name="font-style-attributes"/>
      </fo:block>
      <!-- or -->
      <fo:block>
        <xsl:call-template name="choose-what-attribute-sets-apply"/>
      </fo:block>
    </xsl:template>