XSLT1.0: Multiple values in choose-when in the right part of equation?

Is there any way to put more then one value in the right part of equation?

<xsl:choose>
<xsl:when test="Properties/LabeledProperty[Label='Category Code']/Value = 600,605,610">

This code above returns:

XPath error : Invalid expression
Properties/LabeledProperty[Label='Category Code']/Value = 600,605,610
                                                             ^
compilation error: file adsml2adpay.xsl line 107 element when

The reason I don't want to use 'OR' is because there are around 20 numbers should be in the right part for each 'when' test.

Upvotes: 1

Views: 369

Answers (1)

Tomalak
Tomalak

Reputation: 338316

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:config="http://tempuri.org/config"
  exclude-result-prefixes="config"
>
  <config:categories>
    <value>600</value>
    <value>605</value>
    <value>610</value>
  </config:categories>

  <xsl:variable 
    name   = "vCategories" 
    select = "document('')/*/config:categories/value" 
  />

  <xsl:key
    name   = "kPropertyByLabel"
    match  = "Properties/LabeledProperty/Value"
    use    = "../Label"
  />

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="key('kPropertyByLabel', 'Category Code') = $vCategories">
        <!-- ... -->
      </xsl:when>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

This works because the XPath = operator compares every node from the left hand side to every node on the right hand side when working on node sets (comparable to an SQL INNER JOIN).

Hence all you need to do is create a node set from your individual values. Using a temporary namespace you can do that right in your XSLT file.

Also note that I've introduced an <xsl:key> to make selecting property values by their label more efficient.


EDIT: You could also create an external config.xml file and do this:

<xsl:variable name="vConfig" select="document('config.xml')" /> 

<!-- ... -->

<xsl:when test="key('kPropertyByLabel', 'Category Code') = $vConfig/categories/value">

With XSLT 2.0 the concept of sequences has been added. It's simpler to do the same thing there:

<xsl:when test="key('kPropertyByLabel', 'Category Code') = tokenize('600,605,610', ',')">

This means you could easily pass in the string '600,605,610' as an external parameter.

Upvotes: 2

Related Questions