开发者

How can I combine xsl:attribute and xsl:use-attribute-sets to conditionally use an attribute set?

开发者 https://www.devze.com 2023-01-03 05:08 出处:网络
We have an xml node \"item\" with an attribute \"style\", which is \"Header1\". This style can change however. We have an attribute set named Header1 which defines how this should look in a PDF, gener

We have an xml node "item" with an attribute "style", which is "Header1". This style can change however. We have an attribute set named Header1 which defines how this should look in a PDF, generated through xsl:fo.

This works (the use-attribute-sets is mentioned inline, in the fo:table-cell node):

<xsl:template match="item[@type='label']">
    <fo:table-row>
        <fo:table-cell xsl:use-attribute-sets="Header1">            
             <fo:block>
                 <fo:inline font-size="8pt" >
                    <xsl:value-of select="." />
                </fo:inline>
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
</xsl:template>

But this doesn't (using xsl:attribute, because the attribute @style can also be Header2 for example). It doesn't generate an error, the PDF is created, but the attributes aren't applied.

<xsl:template match="item[@type='label']">
    <fo:table-row>
        <fo:table-cell>         
             <xsl:attribute name="xsl:use-attribute-sets">
                 <xsl:value-of select="@style" />
             </xsl:attribute>
             <fo:block>
                 <fo:inline font-size="8pt" >
                    &开发者_StackOverflowlt;xsl:value-of select="." />
                </fo:inline>
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
</xsl:template>

Does anyone know why? And how we could achieve this, preferably without long xsl:if or xsl:when stuff?


From http://www.w3.org/TR/xslt#attribute-sets

Attribute sets are used by specifying a use-attribute-sets attribute on xsl:element, xsl:copy [...] or xsl:attribute-set elements

From http://www.w3.org/TR/xslt#section-Creating-Elements-with-xsl:element

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

And http://www.w3.org/TR/xslt#copying

<!-- Category: instruction -->
<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:copy>

So, it's clear it can't be an AVT (dynamicly defined).

Note: About literal result element, the specification say: Attribute sets can also be used by specifying an xsl:use-attribute-sets attribute on a literal result element. It's rare vague about allowing AVT. Assume no.

About second example: with that template you're adding a "xsl:use-attribute-sets" attribute into the result tree. It's not iterpreted by the XSLT processor.

Then, what's the solution? You have to get rid of "xsl:use-attribute-sets". Apply a template rule for "@style" and generate the desired attributes there.


Try:

<fo:table-cell xsl:use-attribute-sets="{@style}">


Use a variable to define style, a variable for true, a variable for false, and a variable to reference either one dynamically using string concatenation:

<xsl:variable name="style">
  <xsl:value-of select="concat(boolean(@style),boolean(not(@style) ) )"/>
</xsl:variable>

<xsl:variable name="falsetrue" select="'foo'"/>
<xsl:variable name="truefalse" select="'bar'"/>
<!--...-->


<xsl:value-of select="//xsl:variable/@select[../@name='style']"/>

Or you can have the templates match themselves and call them using the value of "style":

<xsl:template name="Header1" match="xsl:template[@name='Header1']"/>

<xsl:template name="Header2" match="xsl:template[@name='Header2']"/>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号