Page 1 of 1

What's wrong with my quickfix?

Posted: Tue Nov 20, 2018 9:30 pm
by martindholmes
Hi there,

I'm trying to write a Schematron Quick Fix that will tag a block of untagged text as a verse stanza in TEI, using a block of XSLT. This is what I have, based on an example from this forum:

Code: Select all


<pattern xmlns="http://purl.oclc.org/dsdl/schematron"
id="dvpp-noTextInDivOrLg-constraint-rule-15">
<sch:rule xmlns="http://www.tei-c.org/ns/1.0"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
context="tei:div/text()[matches(., '[a-z]+.*&#xA;')] | tei:lg/text()[matches(., '[a-z]+.*&#xA;')]">
<sch:assert test="text()" sqf:fix="tagBlockAsStanza">
Untagged text should probably be tagged as a stanza or a paragraph.
</sch:assert>
<sqf:fix id="tagBlockAsStanza">
<sqf:description>
<sqf:title>Tag this block as a stanza.</sqf:title>
</sqf:description>
<sqf:replace>
<tei:lg>
<xsl:analyze-string select="." regex="'&#xA;\s*[^&#xA;]+'">
<xsl:matching-substring>
<tei:l>
<xsl:value-of select="regex-group(0)"/>
</tei:l>
</xsl:matching-substring>
<xsl:non-matching-substring>
</xsl:non-matching-substring>
</xsl:analyze-string>
</tei:lg>
</sqf:replace>
</sqf:fix>
</sch:rule>
</pattern>
The result is always an empty lg element, with the text deleted, so I must be missing something. Can anyone see what's broken?

All help appreciated,
Martin

Re: What's wrong with my quickfix?

Posted: Wed Nov 21, 2018 12:31 am
by martindholmes
Slightly tweaked version that has the same result, except that I get a linebreak inside the

Code: Select all

<lg>
, which suggests that the regex is failing to match anything:

Code: Select all


<pattern xmlns="http://purl.oclc.org/dsdl/schematron"
id="dvpp-noTextInDivOrLg-constraint-rule-15">
<sch:rule xmlns="http://www.tei-c.org/ns/1.0"
xmlns:sch="http://purl.oclc.org/dsdl/schematron"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
context="tei:div/text() | tei:lg/text()">
<sch:assert test="not(matches(., '[a-z]+.*[\r\n]'))" sqf:fix="tagBlockAsStanza">
Untagged text should probably be tagged as a stanza or a paragraph.
</sch:assert>
<sqf:fix id="tagBlockAsStanza">
<sqf:description>
<sqf:title>Tag this block as a stanza.</sqf:title>
</sqf:description>
<sqf:replace match=".">
<tei:lg>
<xsl:analyze-string select="." regex="'([\r\n]\s*)([^\r\n]+)'">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<tei:l>
<xsl:value-of select="regex-group(2)"/>
</tei:l>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:text>
</xsl:text>
</xsl:non-matching-substring>
</xsl:analyze-string>
</tei:lg>
</sqf:replace>
</sqf:fix>
</sch:rule>
</pattern>
This regex does seem to correctly select the individual lines of text when run as a text search in Oxygen.

Can't figure this one out at all.

Cheers,
Martin

Re: What's wrong with my quickfix?

Posted: Wed Nov 21, 2018 11:16 am
by tavy
Hello Martin,

The quick fix does not work because the regular expression from the "xsl:analyze-string" element has quotes before and after the expression. You should remove the quotes, something like this:

Code: Select all

 <xsl:analyze-string select="." regex="([\r\n]\s*)([^\r\n]+)">
Best Regards,
Octavian

Re: What's wrong with my quickfix?

Posted: Wed Nov 21, 2018 7:06 pm
by martindholmes
Doh! Thanks indeed.

I'd given up and done it a different way, which also works fine:

Code: Select all


  <pattern xmlns="http://purl.oclc.org/dsdl/schematron"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns:teix="http://www.tei-c.org/ns/Examples"
id="dvpp-noTextInDivOrLg-constraint-rule-15">
<sch:rule xmlns="http://www.tei-c.org/ns/1.0"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
context="tei:div/text() | tei:lg/text()">
<sch:assert test="not(matches(., '[a-z]+.*[\r\n]'))" sqf:fix="tagBlockAsStanza">
Untagged text should probably be tagged as a stanza or a paragraph.
</sch:assert>
<sqf:fix id="tagBlockAsStanza">
<sqf:description>
<sqf:title>Tag this block as a stanza.</sqf:title>
</sqf:description>
<sqf:replace match=".">
<xsl:apply-templates mode="tagBlockAsStanza" select="."/>
</sqf:replace>
</sqf:fix>
</sch:rule>
</pattern>

<xsl:template match="tei:div/text()[matches(., '[a-z]+.*[\r\n]')] | tei:lg/text()[matches(., '[a-z]+.*[\r\n]')]" mode="tagBlockAsStanza">
<xsl:text>&#x0a;</xsl:text>
<lg>
<xsl:for-each select="tokenize(., '\n')">
<xsl:if test="normalize-space(.) != ''">
<xsl:value-of select="concat('&#x0a;', replace(., '^(\s+).+', '$1'))"/>
<l><xsl:value-of select="replace(., '^\s+', '')"/></l>
</xsl:if>
</xsl:for-each>

<xsl:text>&#x0a;</xsl:text>
</lg>
<xsl:text>&#x0a;</xsl:text>
</xsl:template>

<xsl:template match="@*|node()" mode="tagBlockAsStanza" priority="-1">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="#current"/>
</xsl:copy>
</xsl:template>