[Home] [By Thread] [By Date] [Recent Entries]

Subject: Re: Optimising XSLT 2.0 restructuring of large SVRL files (Saxon-HE 12.9)
From: "Susanne Wunsch susanne.wunsch@xxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 May 2026 12:32:17 -0000
Hi all,

thanks for the clarification! I admit I sometimes still trip over what
the context node actually is inside current-group(); I keep expecting
children where in fact there are siblings. :-/

One more question, this time about coding style rather than correctness:
which of the following two approaches would experienced XSLT developers
consider better practice?

a) keep all the grouping logic encapsulated within a single template
(i.e. nested xsl:for-each-group plus inline xsl:element constructions), or

b) spread the logic across several templates, dispatched via match and
mode (so each "level" of the hierarchy has its own mode and its own
dedicated templates)?

The variant I have ended up follows approach (b), which I find quite
readable, but I am not sure whether it is considered idiomatic or rather
overengineered. I would be grateful for any general comments on style,
naming, or structure.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:svrl="http://purl.oclc.org/dsdl/svrl"
    xmlns:hsvrl="http://tu-dresden.de/vlp/schematron/hierarchical-svrl"
    exclude-result-prefixes="svrl"
    version="2.0">

<xsl:output method="xml" indent="yes"/>

    <xsl:template match="@*|comment()" mode="restructure">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@*|comment()" mode="#current"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="svrl:*" mode="restructure">
        <xsl:element name="{local-name()}"
namespace="http://tu-dresden.de/vlp/schematron/hierarchical-svrl">
            <xsl:apply-templates select="@*|comment()|node()"
mode="#current"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="*" mode="restructure">
        <xsl:element name="{name()}" namespace="{namespace-uri()}">
            <xsl:apply-templates select="@*|comment()|node()"
mode="#current"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="svrl:schematron-output" mode="restructure">
        <xsl:element name="{local-name()}"
namespace="http://tu-dresden.de/vlp/schematron/hierarchical-svrl">
            <xsl:apply-templates select="@*" mode="#current"/>
            <xsl:comment>
                This is a restructured SVRL document, which does not
comply with ISO 19757-3 Annex D grammar!
            </xsl:comment>
            <xsl:apply-templates select="comment()" mode="#current"/>
            <xsl:apply-templates select="svrl:text" mode="#current"/>
            <xsl:apply-templates
select="svrl:ns-prefix-in-attribute-values" mode="#current"/>
            <xsl:for-each-group select="svrl:active-pattern |
svrl:active-pattern/following-sibling::*"
group-starting-with="svrl:active-pattern">
                <xsl:apply-templates select="current-group()"
mode="restructure_active-pattern"/>
            </xsl:for-each-group>
        </xsl:element>
    </xsl:template>

    <xsl:template match="*" mode="restructure_active-pattern">
        <xsl:if test="self::svrl:active-pattern">
            <xsl:element name="{local-name()}"
namespace="http://tu-dresden.de/vlp/schematron/hierarchical-svrl">
                <xsl:apply-templates select="@* | comment() | *"
mode="restructure"/>
                <xsl:for-each-group select="current-group() except
current()" group-starting-with="svrl:fired-rule">
                    <xsl:apply-templates select="current-group()"
mode="restructure_fired-rule"/>
                </xsl:for-each-group>
            </xsl:element>
        </xsl:if>
    </xsl:template>

    <xsl:template match="*" mode="restructure_fired-rule">
        <xsl:if test="self::svrl:fired-rule">
            <xsl:element name="{local-name()}"
namespace="http://tu-dresden.de/vlp/schematron/hierarchical-svrl">
                <xsl:apply-templates select="@* | comment()"
mode="restructure"/>
                <xsl:apply-templates select="current-group() except
current()" mode="restructure"/>
            </xsl:element>
        </xsl:if>
    </xsl:template>

    <xsl:template match="svrl:fired-rule[@flag = 'ignore']"
mode="restructure_fired-rule"/>

    <xsl:template match="svrl:fired-rule[not(@role)]"
mode="restructure_fired-rule" priority="-1"/>

    <xsl:template
match="svrl:failed-assert[preceding-sibling::*[1]/@flag = 'ignore']"
mode="restructure" priority="2"/>

    <xsl:template
match="svrl:successful-report[preceding-sibling::*[1]/@flag = 'ignore']"
mode="restructure" priority="2"/>

</xsl:stylesheet>

Thanks again for the patient guidance. I have learned a lot from this
thread.

Best regards,
Susanne

Current Thread
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member