Page 1 of 1

Test to see if text contains a string from a list of values

Posted: Fri Nov 06, 2020 5:05 am
by shudson310
I'm trying to create a Schematron rule that will check text nodes against a list of terms in an external document. Basically, I'm trying to see if writers included a product name directly in text instead of using a keyref in DITA.

I'm reading in my external document by:

Code: Select all

<sch:let name="keys"
        value="document('keys-common.ditamap')"/>
I need a test that will check to see if the text nodes contain one of the values from

Code: Select all

$keys//keyword
I can get an exact match using:

Code: Select all

<sch:let name="text" value="text()"/>
        <sch:report id="now001"
            test="$keys//keyword[normalize-space(.) =$text]"
            role="error">
But that only works if the entire node matches. I want to check if the phrase is contained within a larger set of text.

Trying something like this:

Code: Select all

test="$keys//keyword[contains($text, .)]" 
results in:
A sequence of more than one item is not allowed as the first argument of fn:contains() ("
", "
")

Any ideas?

Re: Test to see if text contains a string from a list of values

Posted: Fri Nov 06, 2020 10:21 am
by tavy
Hello Scott ,

I think that a solution can be to count the number of matched keys, then you can write also the matched keys in the assertion message. The pattern must look something like this:

Code: Select all

<sch:pattern>
    <sch:let name="keys" value="document('keys-common.ditamap')//keyword"/>
    <sch:rule context="p">
        <sch:let name="text" value="text()"/>
        <sch:let name="matchedKeys" value="$keys[contains($text, normalize-space(.))]"/>
        <sch:report id="now001" test="count($matchedKeys) > 0" role="error">
            Text contains keywords: <sch:value-of select="$matchedKeys"/>
        </sch:report>
    </sch:rule>
</sch:pattern>
Best Regards,
Octavian

Re: Test to see if text contains a string from a list of values

Posted: Fri Nov 06, 2020 7:19 pm
by shudson310
Unfortunately, I get this error:
A sequence of more than one item is not allowed as the first argument of fn:contains() ("Access to the ", " overview module is granted to a sp...")

Re: Test to see if text contains a string from a list of values

Posted: Mon Nov 09, 2020 10:16 am
by tavy
Hello Scott,

Yes, in case there are multiple text nodes in a paragraph the "text()" function will return a sequence of text nodes. You can replace the "$text" variable with the following one:

Code: Select all

<sch:let name="text" value="."/>
Best Regards,
Octavian