简体   繁体   中英

XSLT counting elements with a matching value

I have a variation on this question

Given the following input XML

<root>
  <zone name="zone1"/>
  <zone name="zone2"/>

  <device name="foo" zone="zone1"/>
  <device name="bar" zone="zone1"/>
</root>

I wish to count - in XSLT - how many devices are in any given zone.

With my limited knowledge I came up with:

...
<xsl:for-each select="zone">
  <tr>
    <td><xsl:value-of select="@name"/></td>
    <td><xsl:value-of select="count(/root/device[@zone = @name]"/></td>
  </tr>

How do I make it clear in the above statement that I want to compare the attribute zone from the <device> element with the name attribute from the current <zone> element?

Or is there perhaps a better/clearer way in achieving my ultimate goal?

It would be best to use XSLT's built-in key mechanism for resolving cross-references:

XSLT 1.0

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

<xsl:key name="device-by-zone" match="device" use="@zone" />

<xsl:template match="root">
    <table>
        <xsl:for-each select="zone">
            <tr>
                <td>
                    <xsl:value-of select="@name"/>
                </td>
                <td>
                    <xsl:value-of select="count(key('device-by-zone', @name))"/>
                </td>
            </tr>
        </xsl:for-each> 
    </table>
</xsl:template>
    
</xsl:stylesheet>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM