Black
Black

Reputation: 5367

xslt to test a set of nodes for value equality

Given the following xml:

<parameterGroup>
    <parameter value="1" name="Level0_stratum">
    </parameter>
    <parameter value="1" name="Level2_stratum">
    </parameter>
    <parameter value="1" name="Level1_stratum">
    </parameter>
    <parameter value="6" name="foo">
    </parameter>       
    <parameter value="9" name="bar">
    </parameter>    
</parameterGroup>

I'd like to derive a boolean variable that indicates whether the @value of ALL the Level*_stratum values are the same, as in this case they are (1).

So far I've been able to group all the pertinent nodes in a set as follows:

select="//parameter[starts-with(@name,'Level') and ends-with(@name,'_stratum') ]"

but I'm not sure the most efficient way to compare all their @value attributes for equality?

Upvotes: 0

Views: 498

Answers (2)

Michael Kay
Michael Kay

Reputation: 163322

If ends-with() is available then you are using XSLT 2.0, therefore distinct-values() is available, so you can simply do

count(distinct-values(
  //parameter[starts-with(@name,'Level') and ends-with(@name,'_stratum') ])/@value))
= 1

Upvotes: 2

JLRishe
JLRishe

Reputation: 101680

I believe this should do what you're looking to do (the value-of lines are not necessary and are just there to show the values of the variables):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="/">
      <xsl:variable 
             name="allStrata"
             select="//parameter[starts-with(@name, 'Level') and
                                 ends-with(@name, '_stratum')]" />
      <xsl:value-of select="concat(count($allStrata), ' strata. ')"/>

      <!-- Determines whether all strata have the same values by comparing them all 
             against the first one. -->
      <xsl:variable name="allStrataEqual" 
                    select="not($allStrata[not(@value = $allStrata[1]/@value)])" />

      <xsl:value-of select="concat('All equal: ', $allStrataEqual)" />
    </xsl:template>
</xsl:stylesheet>

When this is run on your sample input above, the result is:

3 strata. All equal: true

When this is run on your sample input after changing the third value to 8 (or anything else), the result is:

3 strata. All equal: false

Upvotes: 1

Related Questions