Search code examples
xsltxslt-1.0xslt-grouping

Partitioning a list of items based on dynamic criteria


Take a list of bugs

<?xml version="1.0"?>
<bugs>
  <bug> 
    <status>todo</status>
    <content> this is a todo bug </content>
  </bug>

  <bug> 
    <status>closed</status>
    <content>this is a closed bug</content>
  </bug>

  <bug> 
    <status>new</status>
    <content>this is a new bug</content>
  </bug>

  <bug> 
    <status>deferred</status>
    <content>this is a deferred bug</content>
  </bug>

  <bug> 
    <status>todo</status>
    <content>this is another todo bug</content>
  </bug>

</bugs>

What would be an XSLT that would list a given set of "active" bugs and all others?

I was able to construct the "active" half of this question, based on an excellent answer given here: XSLT: Using variables in a key function, which would be the following XSLT:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ext="http://exslt.org/common"
                >

  <xsl:output method="text"/>

  <xsl:param name="pActive">
    <!-- this is supposed to be the dynamic criteria -->
    <a>todo</a>
    <a>new</a>
  </xsl:param>

  <xsl:key name="kBugsByStatus" match="bug" use="normalize-space(status)"/>

  <xsl:variable name="vActive" select="ext:node-set($pActive)/*"/>

  <xsl:template match="/">
    <xsl:text>Active bugs:&#xA;</xsl:text>
    <xsl:apply-templates select="key('kBugsByStatus',$vActive)"/>

    <xsl:text>Other bugs:&#xA;</xsl:text>
    <!-- This is the question: -->
    <xsl:apply-templates select="key('kBugsByStatus',???)"/>

  </xsl:template>


  <xsl:template match="bug">
    <xsl:text>* </xsl:text>
    <xsl:value-of select="normalize-space(content)"/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

Thanks!


Solution

  • Use select="/bugs/bug[not(status = $vActive)]".