xsl-list
[Top] [All Lists]

Re: [xsl] Is this a grouping task?

2019-10-24 05:34:51
                                                                                
                                                                                
       Dimitre,
Thank you for the catch. This should do it.                                
<xsl:copy>
    <xsl:attribute name="rev" select="'changed'"/>
    <xsl:for-each select="./node()">
        <xsl:copy-of select="."/>
    </xsl:for-each>
 </xsl:copy>
Terry Badger


On Wednesday, October 23, 2019, 10:05:39 PM EDT, Dimitre Novatchev 
dnovatchev(_at_)gmail(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote: 





Rick,
This will solve your problem using xsl version 2 using 2 for-each-groups.  

Almost close, with the exception of the problem in this snippet:

                                <xsl:copy>
                                    <xsl:attribute name="rev" 
select="'changed'"/>
                                    <xsl:value-of select="."/>
                                </xsl:copy>

The result of running the proposed solution contains:

  <note rev="changed">
      Content
  </note>


But what Rick requires is:

        <note rev="changed">
            <para>Content</para>
        </note>


Cheers,
Dimitre


On Wed, Oct 23, 2019 at 6:47 PM Terry Badger terry_badger(_at_)yahoo(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
Rick,
This will solve your problem using xsl version 2 using 2 for-each-groups.

    <?xml version="1.0" encoding="UTF-8"?> 
<!-- Terry Badger 2019-10-23 --> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; exclude-result-prefixes="xs" 
    version="2.0"> 
    <xsl:template match="/root"> 
        <xsl:copy> 
            <xsl:apply-templates/> 
        </xsl:copy> 
    </xsl:template> 
    <xsl:template match="topic"> 
        <xsl:copy> 
            <xsl:copy-of select="@*"/> 
            <xsl:for-each-group select="*" group-starting-with="revst"> 
                <xsl:for-each-group select="current-group()" 
group-ending-with="revend"> 
                    <xsl:choose> 
                        <xsl:when test="current-group()/self::*[name() = 
'revst']"> 
                            <xsl:for-each select="current-group()[name() != 
'revst'][name() != 'revend']"> 
                                <xsl:copy> 
                                    <xsl:attribute name="rev" 
select="'changed'"/> 
                                    <xsl:value-of select="."/> 
                                </xsl:copy> 
                            </xsl:for-each> 
                        </xsl:when> 
                        <xsl:otherwise> 
                            <xsl:copy-of select="current-group()"/> 
                        </xsl:otherwise> 
                    </xsl:choose> 
                </xsl:for-each-group> 
            </xsl:for-each-group> 
        </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 


Terry






On Wednesday, October 23, 2019, 03:57:18 AM EDT, Martin Honnen 
martin(_dot_)honnen(_at_)gmx(_dot_)de 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote: 





Am 22.10.2019 um 21:10 schrieb Martin Honnen 
martin(_dot_)honnen(_at_)gmx(_dot_)de:
On 22.10.2019 20:41, Martin Honnen martin(_dot_)honnen(_at_)gmx(_dot_)de 
wrote:
On 22.10.2019 20:07, Rick Quatro rick(_at_)rickquatro(_dot_)com wrote:

I am using XSLT 2 and think this may require a for-each-group solution.
Any advice would be appreciated. Thank you very much.

Thinking about it again, it seems in XSLT 3 simply using an accumulator
makes it even more easy and compact:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy" streamable="yes"
use-accumulators="rev-change"/>

    <xsl:accumulator name="rev-change" as="xs:boolean"
initial-value="false()" streamable="yes">
        <xsl:accumulator-rule match="topic" select="false()"/>
        <xsl:accumulator-rule match="topic/revst" select="true()"/>
        <xsl:accumulator-rule match="topic/revend" select="false()"/>
    </xsl:accumulator>

    <xsl:template match="topic/*[accumulator-before('rev-change')]">
        <xsl:copy>
            <xsl:attribute name="rev">changed</xsl:attribute>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="revst | revend" priority="2"/>

</xsl:stylesheet>

Saxon EE however doesn't like it for streaming and crashes


Michael Kay has already identified the problem with streaming in above
code, using

   <xsl:template
match="topic/*[boolean(accumulator-before('rev-change'))]">


fixes it.






  XSL-List info and archive 
EasyUnsubscribe (by email) 
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>