Subject: Re: [xsl] Using xsl:iterate inside <xsl:for-each-group> xslt 3.0 From: "Martin Honnen martin.honnen@xxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Thu, 13 Aug 2020 19:55:01 -0000 |
I have a set of problems in the following format: <set> <p class="directions">Write <span class="letter">S</span> if <span
class="term">sentence</span>; write <span class="letter">F</span> if <span class="term">fragment</span></p>
<p class="nl">	1.	Sentence (or fragment) here.</p> <p class="nl">	2.	Another sentence/fragment here.</p> <p class="nl">	3.	Yet another.</p> </set>
For a dropdown menu object, I need to replicate the choices in the
directions for each item and number the choices sequentially starting with zero:
<write_choices> <!-- These are the choices for item 1--> <write_choice num='0' letter='S' term='sentence'/> <write_choice num='1' letter='F' term='fragment'/> <!-- These are the choices for item 2--> <write_choice num='2' letter='S' term='sentence'/> <write_choice num='3' letter='F' term='fragment'/> <!-- These are the choices for item 3--> <write_choice num='4' letter='S' term='sentence'/> <write_choice num='5' letter='F' term='fragment'/> </choices>
Not all sets of problems have just two choices like this one. Some have
three, others have more. Because of the variable number of choices, I decided to use grouping. For example, here is a section of the transform that produces a perfect set of <write_choice> elements for each item. The selected node is <p class="nl"> and a copy of <p class='directions'> is stored in <xsl:variable name="myDir" />
group-starting-with="span[@class='letter']">
<write_choices> <xsl:for-each-group select="$myDir/p/*"
select="current-group()[1][self::span[@class='letter']]"/><write_choice> <xsl:attribute name="letter"> <xsl:value-of
</xsl:attribute> <xsl:attribute name="term"> <xsl:value-of select="current-group()[2][self::span[@class='term']]"/> </xsl:attribute> </write_choice> </xsl:for-each-group> </write_choices>
output:
<write_choices> <write_choice letter="S" term="sentence"/> <write_choice letter="F" term="fragment"/> </write_choices>
I hope I have now better understood the problem, I think you can group your p[@class = 'directions']/* elements once and store the result, for instance as a sequence of maps.
Then you can push the map for each of the p[@class = 'nl'] through a template creating a write_choice:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all">
<xsl:template match="set[p[@class = 'nl']]"> <xsl:variable name="groups" as="map(xs:string, element())*"> <xsl:for-each-group select="p[@class = 'directions']/*" group-starting-with="span[@class = 'letter']"> <xsl:sequence select="map { 'letter' : ., 'term' : current-group()[2] }"/> </xsl:for-each-group> </xsl:variable> <write_choices> <xsl:apply-templates select="p[@class = 'nl'] ! $groups"/> </write_choices> </xsl:template>
<xsl:template match=".[. instance of map(xs:string, element())]"> <write_choice num="{position() - 1}" letter="{?letter}" term="{?term}"/> </xsl:template>
I certainly see no need to nest for-each-group and iterate but you could of course use iterate instead of the apply-templates:
<xsl:template match="set[p[@class = 'nl']]"> <xsl:variable name="groups" as="map(xs:string, element())*"> <xsl:for-each-group select="p[@class = 'directions']/*" group-starting-with="span[@class = 'letter']"> <xsl:sequence select="map { 'letter' : ., 'term' : current-group()[2] }"/> </xsl:for-each-group> </xsl:variable> <write_choices> <xsl:iterate select="p[@class = 'nl'] ! $groups"> <write_choice num="{position() - 1}" letter="{?letter}" term="{?term}"/> </xsl:iterate> </write_choices> </xsl:template>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Using xsl:iterate inside , Terry Ofner tdofner@ | Thread | Re: [xsl] Using xsl:iterate inside , Terry Ofner tdofner@ |
Re: [xsl] Using xsl:iterate inside , Terry Ofner tdofner@ | Date | Re: [xsl] Using xsl:iterate inside , Terry Ofner tdofner@ |
Month |