1
votes

I'm using XSLT 1.0 and am trying to group by two elements in my XML. Basically I'd like to transform the following XML:

<requirements>
  <item>
    <category>Admin</category>
    <functionality>View Data</functionality>
    <requirement>The system shall do 1</requirement>
  </item>
  <item>
    <category>Admin</category>
    <functionality>View Data</functionality>
    <requirement>The system shall do 2</requirement>
  </item>
  <item>
    <category>Admin</category>
    <functionality>Query Data</functionality>
    <requirement>The system shall do 3</requirement>
  </item>
  <item>
    <category>Admin</category>
    <functionality>Query Data</functionality>
    <requirement>The system shall do 4</requirement>
  </item>
</requirements>

Into this:

<requirements>
  <item>
    <category>Admin</category>
    <functionality>View Data</functionality>
    <requirement id ="1">The system shall do 1</requirement>
    <requirement id ="2">The system shall do 2</requirement>
  </item>
  <item>
    <category>Admin</category>
    <functionality>Query Data</functionality>
    <requirement id="1">The system shall do 3</requirement>
    <requirement id="2">The system shall do 4</requirement>
  </item>
</requirements>

I just don't have enough experience with XSLT yet to implement the Muenchian method correctly.

Any help is greatly appreciated.

1
Can you explain the logic behind? What I could think of is you are trying to group items by functionality and the @id on requirement has the value n for the nth requirement. Please feel free to post your try here.Lingamurthy CS
"trying to group by two elements" Which two?michael.hor257k
@Lingamurthy CS -- Your explanation is spot on. I guess I really couldn't visualize what I actually needed.Tony

1 Answers

0
votes

If you use a key that concatenates category and functionality, as in <xsl:key name="group" match="item" use="concat(category, '|', functionality)"/>, then you can use the normal Muenchian grouping:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>

<xsl:key name="group" match="item" use="concat(category, '|', functionality)"/>

<xsl:template match="requirements">
  <xsl:copy>
    <xsl:apply-templates select="item[generate-id() = generate-id(key('group', concat(category, '|', functionality))[1])]"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="item">
  <xsl:copy>
    <xsl:copy-of select="category | functionality"/>
    <xsl:apply-templates select="key('group', concat(category, '|', functionality))/requirement"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="requirement">
  <xsl:copy>
    <xsl:attribute name="id"><xsl:value-of select="position()"/></xsl:attribute>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>