Page 1 of 1

Schematron quick fix to set parent element

Posted: Tue Aug 25, 2020 11:53 am
by ann.jensen
Hi,
I know this is not a Schematron forum but I see others successfully posting on the language so thought I would try.....
I have a Schematron rule that checks the parent of a DITA element (shortdesc) and alerts if it is not the expected parent (abstract).
I would like to add a quick fix to set the parent element if incorrect.
Is this possible with Schematron Quick Fix language?
Any feedback appreciated,
Regards,
Ann

Re: Schematron quick fix to set parent element

Posted: Tue Aug 25, 2020 12:50 pm
by tavy
Hello Ann,

I created a Schematron rule that checks if the short description element is in an abstract element. If is not, provides also a quick fix that moves the short description element in an abstract element. In case an abstract element already exists, will move the short description in that element. If there is no abstract element as sibling, a new abstract element will be created and the short description will be added inside it.

Code: Select all

<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
    xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <sch:pattern>
        <sch:rule context="shortdesc">
            <sch:assert test="parent::abstract" sqf:fix="moveToAbstract moveToExistingAbstract">
                The short description must be added in an abstract element
            </sch:assert>
            <!-- Check if there is an abstarct element -->
            <sch:let name="abstractElem" value="preceding-sibling::abstract | following-sibling::abstract"/>
            
            <!-- Create an abstract element and add the short description -->
            <sqf:fix id="moveToAbstract" use-when="not($abstractElem)">
                <sqf:description>
                    <sqf:title>Move short description in an abstract element</sqf:title>
                </sqf:description>
                <sqf:replace>
                    <abstract>
                        <xsl:apply-templates mode="copyExceptClass" select="."/>
                    </abstract>
                </sqf:replace>
            </sqf:fix>
            
            <!-- Move the short description in the abstract element-->
            <sqf:fix id="moveToExistingAbstract" use-when="$abstractElem">
                <sqf:description>
                    <sqf:title>Move short description in the abstract element</sqf:title>
                </sqf:description>
                <sch:let name="shortDesc">
                    <xsl:apply-templates mode="copyExceptClass" select="."/>
                </sch:let>
                <sqf:add match="$abstractElem" select="$shortDesc"/>
                <sqf:delete/>
            </sqf:fix>
        </sch:rule>
    </sch:pattern>  
    
    
    <!-- Template used to copy the current node -->
    <xsl:template match="node() | @*" mode="copyExceptClass">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="node() | @*" mode="copyExceptClass"/>
        </xsl:copy>
    </xsl:template>
    <!-- Template used to skip the @class attribute from being copied -->
    <xsl:template match="@class" mode="copyExceptClass"/>
</sch:schema>
Best Regards,
Octavian

Re: Schematron quick fix to set parent element

Posted: Tue Aug 25, 2020 2:54 pm
by ann.jensen
Wow, thanks so much for that Octavian, much appreciated.
Regards,
Ann