Reputation: 329
I have the following template to pass back a filter attribute:
<xsl:template name="have_arch_attrib">
<xsl:variable name="condition_values"/>
<xsl:variable name="security_values"/>
<xsl:variable name="arch_values"/>
<xsl:choose>
<xsl:when test=".[@arch]"> <!-- add arch values -->
<xsl:variable name="arch_values" select=".[@arch]" />
</xsl:when>
<xsl:when test=".[@condition]"> <!-- Add condition values -->
<xsl:variable name="condition_values" select=".[@condition]" />
</xsl:when>
<xsl:when test=".[@security]"> <!-- Add condition values -->
<xsl:variable name="security_values" select=".[@security]"/>
</xsl:when>
</xsl:choose>
<xsl:attribute name="filter"><xsl:value-of select="concat($condition_values, $security_values, $arch_values)"/></xsl:attribute>
I've looked at other solutions, but i can't see how they can apply to this?
Can anyone give me a clue?
Thanks,
Russ
Upvotes: 1
Views: 2057
Reputation: 9627
There are some problems in your template.
<xsl:when test="@arch">
.Interpreting your template as pseudo code would be: The attribute filter should get the value of the first existing attribute (out of arch, condition or security). Which would be this xlst:
<xsl:template name="have_arch_attrib">
<xsl:attribute name="filter">
<xsl:choose>
<xsl:when test="@arch">
<xsl:value-of select="@arch" />
</xsl:when>
<xsl:when test="@condition">
<xsl:value-of select="@condition" />
</xsl:when>
<xsl:when test="@security">
<xsl:value-of select="@security" />
</xsl:when>
</xsl:choose>
</xsl:attribute>
</xsl:template>
Based on your comment to the answer from Ian Roberts:
"The only reason i was checking if the attributes existed, was that i needed to delimit any attributes with a ",". I can see how i can changes these aftwerwards"
Try something like this:
<xsl:attribute name="filter">
<xsl:if test="@arch">
<xsl:value-of select="@arch" />
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:if test="@condition">
<xsl:value-of select="@condition" />
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:if test="@security">
<xsl:value-of select="@security" />
</xsl:if>
</xsl:attribute>
</xsl:template>
This is surly still not perfect, but your statements are not clear enough.
If "delimit" means separate the above template will generate a not wonted terminating comma. To avoid this you can try:
<xsl:template name="have_arch_attrib">
<xsl:attribute name="filter">
<xsl:for-each select="@arch | @condition | @security ">
<xsl:value-of select="." />
<xsl:if test="position() != last()" >
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:attribute>
</xsl:template>
Upvotes: 1
Reputation: 122364
The error message is pretty descriptive - you can't add attribute nodes to an element using <xsl:attribute>
after you've added any child nodes (elements, text nodes, comments or processing instructions). So the problem that causes that error message is in what happens before you call the have_arch_attrib
template rather than in the template itself.
That said, the template you have given here won't produce the result you want, because you can't modify the value of an XSLT variable after it has been created. You will need to re-structure the template to put the <xsl:choose>
inside the <xsl:attribute>
, rather than trying to use variables to carry the various values around. Or in fact just lose the choose altogether as it's not an error to ask for the value-of
an attribute that doesn't exist, you simply get the empty string.
<xsl:attribute name="filter">
<xsl:value-of select="@condition"/>
<xsl:value-of select="@security"/>
<xsl:value-of select="@arch"/>
</xsl:attribute>
Upvotes: 2