0

I was looking at the Muenchian method for grouping with xslt,

The data is similar to this

<Root>
  <Entries>
    <Entry Attribute="A"/>
    <Entry Attribute="B"/>
    <Entry Attribute="C"/>
  </Entries>
</Root>

But in addition I needed to have a predefined sort order - on atttributes of my elements. So I was looking at having a custom xml section in the xslt with sort order and inserting it into a variable something like this

<xsl:variable name="sortorder"select="document('')/*/my:data/my:ordering/my:value"/>

Values being e.g. C, B, A which is order and also grouping header

Then it occured to me that instead of using the key() function in the Muenchian method, I could simply loop through the values of the variable.

Like this

<xsl:template match="Entries">
<xsl:for-each select="$sortorder/value">
  <groupheader><xsl:value-of select="."/></groupheader>

... and then apply templates

<xsl:apply-templates select="Entry[@sortattribute=current()"></xsl:apply-templates> 

But I havent gotten it to work. Any tips on how to achieve this? Am I on the right track? I suspect that I am throwing the processor off with the looping over the variable in the context of the <Entry>s but I don't know how to correct it.

2
  • Usually fuller coding output not sparse one-liners especially XSLT to see all templates, sample data, and desired results help to put specifics on general terms. Commented Dec 23, 2015 at 1:21
  • "I don't know how to correct it." I don't know how to correct it either, because you're not showing us a complete stylesheet. See: stackoverflow.com/help/mcve Commented Dec 23, 2015 at 7:49

1 Answer 1

1

Here's a generalized example you could use as a guide:

XML

<input>
    <item category="Winter">Alpha</item>
    <item category="Autumn">Bravo</item>
    <item category="Spring">Charlie</item>
    <item category="Summer">Delta</item>
    <item category="Spring">Echo</item>
    <item category="Autumn">Foxtrot</item>
    <item category="Spring">Golf</item>
    <item category="Summer">Hotel</item>
    <item category="Winter">India</item>
    <item category="Autumn">Juliet</item>
    <item category="Summer">Kilo</item>
    <item category="Winter">Lima</item>
    <item category="Summer">Mike</item>
    <item category="Spring">November</item>
    <item category="Spring">Oscar</item>
    <item category="Autumn">Papa</item>
    <item category="Winter">Quebec</item>
    <item category="Summer">Romeo</item>
    <item category="Spring">Sierra</item>
    <item category="Summer">Tango</item>
    <item category="Spring">Uniform</item>
    <item category="Autumn">Victor</item>
    <item category="Summer">Whiskey</item>
    <item category="Winter">Xray</item>
    <item category="Summer">Yankee</item>
    <item category="Autumn">Zulu</item>
</input>

XSLT 1.0

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

<my:categories>
    <category>Spring</category>
    <category>Summer</category>
    <category>Autumn</category>
    <category>Winter</category>
</my:categories>

<xsl:variable name="root" select="/"/>

<xsl:template match="/">
    <output>
        <xsl:for-each select="document('')/xsl:stylesheet/my:categories/category">
            <group category="{.}">
                <xsl:apply-templates select="$root/input/item[@category=current()]"/>
            </group>
        </xsl:for-each> 
    </output>
</xsl:template>

<xsl:template match="item">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

Result

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <group category="Spring">
      <item category="Spring">Charlie</item>
      <item category="Spring">Echo</item>
      <item category="Spring">Golf</item>
      <item category="Spring">November</item>
      <item category="Spring">Oscar</item>
      <item category="Spring">Sierra</item>
      <item category="Spring">Uniform</item>
   </group>
   <group category="Summer">
      <item category="Summer">Delta</item>
      <item category="Summer">Hotel</item>
      <item category="Summer">Kilo</item>
      <item category="Summer">Mike</item>
      <item category="Summer">Romeo</item>
      <item category="Summer">Tango</item>
      <item category="Summer">Whiskey</item>
      <item category="Summer">Yankee</item>
   </group>
   <group category="Autumn">
      <item category="Autumn">Bravo</item>
      <item category="Autumn">Foxtrot</item>
      <item category="Autumn">Juliet</item>
      <item category="Autumn">Papa</item>
      <item category="Autumn">Victor</item>
      <item category="Autumn">Zulu</item>
   </group>
   <group category="Winter">
      <item category="Winter">Alpha</item>
      <item category="Winter">India</item>
      <item category="Winter">Lima</item>
      <item category="Winter">Quebec</item>
      <item category="Winter">Xray</item>
   </group>
</output>

Note the use of the $root variable to return the context to the input XML document.

Sign up to request clarification or add additional context in comments.

1 Comment

The $root variable did the trick. Thanks for your excellent answer!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.