Subject: [xsl] Recursion and for-each-group (XSLT 2.0) From: JBryant@xxxxxxxxx Date: Tue, 5 Apr 2005 13:33:46 -0500 |
Hi, all, Apologies in advance for a long message. I'm trying to give a complete description of the problem. I have defined a set of index entries as nested indexentry elements in my source file. Then, in the XSL, I am trying to use a single template to group the entries at each level. That much is working, but I am getting multiple results. I've tried a number of solutions, but I'm stumped. Here's the source file: <book> <chapter title="Chapter1"> <indexentries> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111"/> </indexentry> </indexentry> </indexentry> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word112"> <indexentry term="word1121"/> </indexentry> </indexentry> </indexentry> <indexentry term="word1"> <indexentry term="word12"/> </indexentry> <indexentry term="word2"/> </indexentries> </chapter> <chapter title="Chapter2"> <indexentries> <indexentry term="word3"> <indexentry term="word31"> <indexentry term="word311"> <indexentry term="word3111"/> </indexentry> </indexentry> </indexentry> <indexentry term="word3"> <indexentry term="word32"/> </indexentry> <indexentry term="word4"/> </indexentries> <topic title="Topic21"> <indexentries> <indexentry term="word5"> <indexentry term="word51"> <indexentry term="word511"> <indexentry term="word5111"/> </indexentry> </indexentry> </indexentry> <indexentry term="word5"> <indexentry term="word52"/> </indexentry> <indexentry term="word6"/> </indexentries> </topic> </chapter> </book> Here's my current best shot at a transform: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xsl:variable name="indexentries"> <indexentries> <xsl:for-each select="//indexentries/indexentry"> <indexentry term="{@term}" target="{generate-id(ancestor::*[indexentries][1])}"> <xsl:copy-of select="indexentry"/> </indexentry> </xsl:for-each> </indexentries> </xsl:variable> <xsl:for-each select="$indexentries"> <xsl:apply-templates/> </xsl:for-each> </xsl:template> <xsl:template match="indexentry"> <xsl:variable name="term" select="@term"/> <xsl:for-each-group select="//indexentry[@term=$term]" group-by="@term"> <indexentry term="{@term}"> <xsl:choose> <xsl:when test="indexentry"> <xsl:apply-templates select="current-group()/indexentry"/> </xsl:when> <xsl:otherwise> <xsl:attribute name="target" select="ancestor-or-self::*[@target]/@target"/> </xsl:otherwise> </xsl:choose> </indexentry> </xsl:for-each-group> </xsl:template> </xsl:stylesheet> Here's the output from applying that stylesheet to the source file: <?xml version="1.0" encoding="UTF-8"?> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word12" target="d1e3"/> </indexentry> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word12" target="d1e3"/> </indexentry> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word12" target="d1e3"/> </indexentry> <indexentry term="word2" target="d1e3"/> <indexentry term="word3"> <indexentry term="word31"> <indexentry term="word311"> <indexentry term="word3111" target="d1e38"/> </indexentry> </indexentry> <indexentry term="word32" target="d1e38"/> </indexentry> <indexentry term="word3"> <indexentry term="word31"> <indexentry term="word311"> <indexentry term="word3111" target="d1e38"/> </indexentry> </indexentry> <indexentry term="word32" target="d1e38"/> </indexentry> <indexentry term="word4" target="d1e38"/> <indexentry term="word5"> <indexentry term="word51"> <indexentry term="word511"> <indexentry term="word5111" target="d1e61"/> </indexentry> </indexentry> <indexentry term="word52" target="d1e61"/> </indexentry> <indexentry term="word5"> <indexentry term="word51"> <indexentry term="word511"> <indexentry term="word5111" target="d1e61"/> </indexentry> </indexentry> <indexentry term="word52" target="d1e61"/> </indexentry> <indexentry term="word6" target="d1e61"/> And here's what I am aiming for: <?xml version="1.0" encoding="UTF-8"?> <indexentry term="word1"> <indexentry term="word11"> <indexentry term="word111"> <indexentry term="word1111" target="d1e3"/> </indexentry> <indexentry term="word112"> <indexentry term="word1121" target="d1e3"/> </indexentry> </indexentry> <indexentry term="word12" target="d1e3"/> </indexentry> <indexentry term="word2" target="d1e3"/> <indexentry term="word3"> <indexentry term="word31"> <indexentry term="word311"> <indexentry term="word3111" target="d1e38"/> </indexentry> </indexentry> <indexentry term="word32" target="d1e38"/> </indexentry> <indexentry term="word4" target="d1e38"/> <indexentry term="word5"> <indexentry term="word51"> <indexentry term="word511"> <indexentry term="word5111" target="d1e61"/> </indexentry> </indexentry> <indexentry term="word52" target="d1e61"/> </indexentry> <indexentry term="word6" target="d1e61"/> As you can see, multiple nodes are appearing in the output tree. I'm using Saxon 8.3, but I very much doubt the processor is the issue. Thanks much. Jay Bryant Bryant Communication Services (presently consulting at Synergistic Solution Technologies)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] How to use multiple xsl:i, Pieter Reint Siegers | Thread | RE: [xsl] Recursion and for-each-gr, Michael Kay |
Re: [xsl] Something similar to mana, Luke Shannon | Date | RE: [xsl] Something similar to mana, Michael Kay |
Month |