Schematron rules for moving the position of an element

Having trouble installing Oxygen? Got a bug to report? Post it all here.
antoterrence
Posts: 30
Joined: Sat May 04, 2019 5:55 pm

Schematron rules for moving the position of an element

Post by antoterrence »

Hi,
We have some issues with the content migrated from another source. Wondering if we can use Schematron rules to provide quick fixes. I know we can use Schematron to replace elements. However, is it possible to change the position of a sibling element so that it becomes a child of a preceding element, with schemetron quick fixes?

For example, let's imagine that I refactor certain step elements to stepresult. Is it possible to move each of those stepresult elements to the preceding step using Schematron?

Your help will be much appreciated.
tavy
Posts: 364
Joined: Thu Jul 01, 2004 12:29 pm

Re: Schematron rules for moving the position of an element

Post by tavy »

Hi,

If I understood correctly you have a structure something like this:

Code: Select all

<step>
   <cmd>test2</cmd>
</step>
<stepresult>2</stepresult>
And you want to move the "stepresult" element in the "step" element, something like this:

Code: Select all

<step>
   <cmd>test2</cmd>
   <stepresult>2</stepresult>
</step>
A solution is to create a Schematron schema and a rule that will check this condition. Then add some quick fixes that will move the current "stepresult" element in the "step" element, or a quick fix that will move all the "stepresult" elements previous "step" element. The Schematron must look something like this:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<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="stepresult">
            <sch:report test="preceding-sibling::element()[1]/name() = 'step'" sqf:fix="moveElement moveAllElements">
                The stepresult must be added in the previus step element.
            </sch:report>
            
            <sqf:fix id="moveElement">
                <sqf:description>
                    <sqf:title>Move stepresult in previus step</sqf:title>
                </sqf:description>
                <sqf:add position="last-child" match="preceding-sibling::element()[1]">
                    <xsl:apply-templates mode="copyExceptClass" select="following-sibling::stepresult[1]"/>
                </sqf:add>
                <sqf:delete match="."/>
            </sqf:fix>
            
            <sqf:fix id="moveAllElements">
                <sqf:description>
                    <sqf:title>Move all stepresult in previus step</sqf:title>
                </sqf:description>
                <sqf:add position="last-child" match="//stepresult[preceding-sibling::element()[1]/name() = 'step']/preceding-sibling::element()[1]">
                    <xsl:apply-templates mode="copyExceptClass" select="following-sibling::stepresult[1]"/>
                </sqf:add>
                <sqf:delete match="//stepresult[preceding-sibling::element()[1]/name() = 'step']"/>
            </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>
I used a copy template "copyExceptClass" to avoid copying the default DITA @class attributes.

Also, if you need to apply this rule on multiple files maybe is better to create an XML refactoring action. You can read more about refactoring actions on our website:
https://www.oxygenxml.com/doc/versions/ ... tools.html
https://www.oxygenxml.com/events/2015/w ... oring.html

Regards,
Octavian
Octavian Nadolu
<oXygen/> XML Editor
http://www.oxygenxml.com
Radu
Posts: 9041
Joined: Fri Jul 09, 2004 5:18 pm

Re: Schematron rules for moving the position of an element

Post by Radu »

Hi,

An example of an XML refactoring action which moves an element as a child of its preceding sibling can be found here:

viewtopic.php?p=54141#p54126

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com
Post Reply