Basic Schematron Quick Fix Operations

There are four basic operations that can be executed in a Schematron Quick Fix: Add, Delete, Replace, and String Replace.

Add

The <sqf:add> element allows you to add a node to the instance. An anchor node is required to select the position for the new node. The anchor node can be selected by the match attribute. Otherwise, it is selected by the context attribute of the rule.

The target attribute defines the name of the node to be added. It is required if the value of the node-type attribute is set to anything other than "comment".

The <sqf:add> element has a position attribute and it determines the position relative to the anchor node. The new node could be specified as the first child of the anchor node, the last child of the anchor node, before the anchor node, or after the anchor node (first-child is the default value). If you want to add an attribute to the anchor node, do not use the position attribute.

Note: If you insert an element and its content is empty, Oxygen XML Editor plugin will insert the required element content.
An Example of the <sqf:add> Element:
<schema xmlns="http://purl.oclc.org/dsdl/schematron"
   xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
 queryBinding="xslt2">
   <pattern>
     <rule context="head">
        <assert test="title" sqf:fix="addTitle">title element missing.</assert>
        <sqf:fix id="addTitle">
            <sqf:description>
                <sqf:title>Insert title element.</sqf:title>
            </sqf:description>
           <sqf:add target="title" node-type="element">Title text</sqf:add>
        </sqf:fix>
     </rule>
   </pattern>
</schema>
Specific Add Operations:
  • Insert Element - To insert an element, use the <sqf:add> element, set the value of the node-type to "element", and specify the element QName with the target attribute. If the element has a prefix, it must be defined in the Schematron using a namespace declaration (<ns uri="namespace" prefix="prefix"/>).
  • Insert Attribute - To insert an attribute, use the <sqf:add> element, set the value of the node-type to "attribute", and specify the attribute QName with the target attribute. If the attribute has a prefix, it must be defined in the Schematron using a namespace declaration (<ns uri="namespace" prefix="prefix"/>).
  • Insert Fragment - If the node-type is not specified, the <sqf:add> element will insert an XML fragment. The XML fragment must be well formed. You can specify the fragment in the add element or by using the select attribute.
  • Insert Comment - To insert a comment, use the <sqf:add> element and set the value of the node-type to "comment".
  • Insert Processing Instruction - To insert a processing instruction, use the <sqf:add> element, set the value of the node-type to "pi" or "processing-instruction", and specify the name of the processing instruction in the target attribute.
Delete
The <sqf:delete> element allows you to remove any type of node (such as elements, attributes, text, comments, or processing instructions). To specify nodes for deletion the <sqf:delete> element can include a match attribute that is an XPath expression (the default value is .). If the match attribute is not included, it deletes the context node of the Schematron rule.
An Example of the <sqf:delete> Element:
<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2" 
    xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
    <pattern>
        <rule context="*[@xml:lang]">
            <report test="@xml:lang" sqf:fix="remove_lang">
                The attribute "xml:lang" is forbidden.</report>
            <sqf:fix id="remove_lang">
                <sqf:description>
                    <sqf:title>Remove "xml:lang" attribute</sqf:title>
                </sqf:description>
                <sqf:delete match="@xml:lang"/>
            </sqf:fix>
        </rule>
    </pattern>
</schema>
Replace
The <sqf:replace> element allows you to replace nodes. Similar to the <sqf:delete> element, it can include a match attribute. Otherwise, it replaces the context node of the rule. The <sqf:replace> element has three tasks. It identifies the nodes to be replaced, defines the replacing nodes, and defines their content.
An Example of the <sqf:replace> Element:
<schema xmlns="http://purl.oclc.org/dsdl/schematron"
    xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
 queryBinding="xslt2">
    <pattern>
        <rule context="title">
            <report test="exists(ph)" sqf:fix="resolvePh" role="warn">
                ph element is not allowed in title.</report>
            <sqf:fix id="resolvePh">
                <sqf:description>
                    <sqf:title>Change the ph element into text</sqf:title>
                </sqf:description>
                <sqf:replace match="ph">
                    <value-of select="."/>
                </sqf:replace>
            </sqf:fix>
        </rule>
    </pattern>
</schema>
Other Attributes for Replace Operations:
  • node-type - Determines the type of the replacing node. The permitted values include:
    • keep - Keeps the node type of the node to be replaced.
    • element - Replaces the node with an element.
    • attribute - Replaces the node with an attribute.
    • pi - Replaces the node with a processing instruction.
    • comment - Replaces the node with a comment.
  • target - By using a QName it gives the replacing node a name. This is necessary when the value of the node-type attribute is anything other than "comment".
  • select - Allows you to choose the content of the replacing nodes. You can use XPath expressions with the select attribute. If the select attribute is not specified then the content of the <sqf:replace> element is used instead.
String Replace
The <sqf:stringReplace> element is different from the others. It can be used to find a sub-string of text content and replace it with nodes or other strings.
Attributes for the String Replace Operation:
  • match - Allows you to select text nodes that contain the sub-strings you want to replace.
  • select - Allows you to select the replacing fragment, in case you do not want to set it in the content of the stringReplace element.
  • regex - Matches the sub-strings using a regular expression.
    Note: Consider the following information about using regular expressions in the stringReplace element:
Attention: The context of the content within the <sqf:stringReplace> element is set to the whole text node, rather than the current sub-string.
An Example of the <sqf:stringReplace> Element:
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron"
    xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
 queryBinding="xslt2">
    <sch:pattern>
        <sch:rule context="text()">
            <sch:report test="matches(., '[oO][xX]ygen')"
 sqf:fix="changeWord">The oXygen word is not allowed</sch:report>
            <sqf:fix id="changeWord">
                <sqf:description>
                    <sqf:title>Replace word with product</sqf:title>
                </sqf:description>
                <sqf:stringReplace regex="[oO][xX]ygen"><ph keyref="product"/>
                </sqf:stringReplace>
            </sqf:fix>
        </sch:rule>
    </sch:pattern>
</sch:schema>