XSLT:如何优化基于多条件的变量赋值
Great question! Your current xsl:choose approach works, but we can make this cleaner and more maintainable depending on your XSLT version. Let's go through a few optimized options:
Option 1: Use XSLT 2.0+ Conditional Expressions (Simplest for Linear Conditions)
If you're working with XSLT 2.0 or later, you can replace the nested xsl:choose with a concise inline conditional expression. This cuts down on boilerplate tag noise while keeping logic easy to follow:
<xsl:variable name="attribute-name" select=" if ($var1 = 1) then 'attr1' else if ($var2 = 1) then 'attr2' else if ($var3 = 1) then 'attr3' else 'attr' "/>
This reads like a plain English "if-else" chain and avoids the need for multiple <xsl:when> tags. Perfect for straightforward, linear condition checks like yours.
Option 2: Use a Map (Best for Scalable/Extensible Mappings)
If you anticipate adding more variable-attribute pairs later, using a map (XSLT 3.0+) makes your code far easier to maintain. You define the mappings in one place, then fetch the correct value with minimal logic:
<!-- Define your variable-to-attribute mappings once --> <xsl:variable name="attr-map" as="map(xs:string, xs:string)" select=" map { 'var1:1': 'attr1', 'var2:1': 'attr2', 'var3:1': 'attr3' } "/> <!-- Fetch the matching attribute name, fall back to 'attr' if none match --> <xsl:variable name="attribute-name" select=" ($attr-map[concat('var1:', $var1)], $attr-map[concat('var2:', $var2)], $attr-map[concat('var3:', $var3)], 'attr')[1] "/>
Now, if you need to add a new var4 that maps to attr4, you only update the attr-map—no need to touch the conditional logic. This is especially useful for larger sets of mappings.
Option 3: XSLT 1.0 Compatibility (Legacy Environments)
If you're stuck on XSLT 1.0 (common in older systems), you can still clean things up by using a node-set to simulate mappings (requires an extension like EXSLT):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl" > <!-- ... --> <xsl:variable name="attr-mappings"> <mapping test="{$var1=1}" value="attr1"/> <mapping test="{$var2=1}" value="attr2"/> <mapping test="{$var3=1}" value="attr3"/> </xsl:variable> <xsl:variable name="attribute-name" select=" (exsl:node-set($attr-mappings)/mapping[@test='true']/@value | 'attr')[1] "/> </xsl:stylesheet>
This centralizes your mappings just like the XSLT 3.0 map, making future edits simpler than updating a long chain of <xsl:when> tags.
Final Note
All these options work seamlessly with your existing attribute-setting code:
<tag> <xsl:attribute name="{$attribute-name}">Something</xsl:attribute> <!-- ... --> </tag>
Pick the approach that fits your XSLT version and how likely you are to extend the mappings later!
内容的提问来源于stack exchange,提问作者aronadaal

