2017-10-20 83 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'。所以它不是真的幫助我,因爲有同樣的問題(我不能通過變量名稱調用模板)。在模板的情況下,我必須讓一個巨人選擇應用哪一個。這就是我現在正在使用屬性集所做的事情。至少它縮短了一些代碼。 :) 我想現在沒有真正的解決方法,但謝謝你的答案! –