2017-10-20 56 views
0

我有一个与xsl:use-attribute-sets有关的问题。 我想要具有可变属性集的元素。 例如:XSLT变量属性集

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

此方法不起作用。 我尝试了一种解决方法,并得出结论,可以通过for-each来添加属性集的属性。 例如:

<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> 

这种方法允许我将属性添加到元素。问题是,如果某个属性包含一个xsl元素(如choose),则处理不当。

是否有可能像这样评估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

我有关于XSL一个问题:使用属性集。我想要有 元素,它们具有可变的属性集。 [...] 这种方法不起作用。

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

我试图做一个变通方法和得出的结论,这是 可以通过 的for-each要添加的属性设置的属性。例如:

<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> 

此方法允许我将属性添加到元素。

您正在读取样式表文档作为附加的输入文档,并将其转换为将< xsl:attribute>元素发送到结果树中。它同时又聪明又可怕。

的 问题是,如果一个属性包含像选择, 一个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> 
    
+0

谢谢您的回答。你的第二种方法很有趣。尽管模板名称也必须是'QNames'。所以它不是真的帮助我,因为有同样的问题(我不能通过变量名称调用模板)。在模板的情况下,我必须让一个巨人选择应用哪一个。这就是我现在正在使用属性集所做的事情。至少它缩短了一些代码。 :) 我想现在没有真正的解决方法,但谢谢你的答案! –