[Schematron] bug report and patch (Re: including keys)
Lars Huttar
lars_huttar at sil.org
Tue Jul 6 18:33:17 EDT 2010
In case anyone else is looking for a way to do this...
I'm surprised that no one mentioned that there is an experimental
feature in the "leading implementation" of Schematron, to include the
children of the href'd element.
"The proposed behaviour for the update to ISO Schematron has been
implemented. If an include points to an element with the same name as
the parent, then that element's contents will be included. This supports
the merge style of inclusion."
This is in the implementation at
http://www.schematron.com/implementation.html
Specifically in http://www.schematron.com/tmp/iso-schematron-xslt2.zip
in iso_dsdl_include.xsl
That sounds perfect for what I need... then I can make the included
document something like:
<iso:schema>
<xsl:key ... />
<xsl:key ... />
...
</iso:schema>
and thus I can include multiple keys into my document with one
<iso:include>.
The code explicitly allows xsl:* elements:
<xsl:variable name="theContainedFragments"
select="$theDocument_2/*/iso:* |
$theDocument_2/*/xsl:* | $theDocument_2/*/xhtml:*" />
which is very good news for including a set of <xsl:key> elements.
Unfortunately, the implementation seems incomplete...
Line 483 says
<!-- case 2 -->
<xsl:when
test=" $theFragment_2/self::iso:schema
or $theContainedFragments/self::iso:schema">
<xsl:message>Schema error: Use include
to include fragments, not a whole schema
</xsl:message>
</xsl:when>
But this does not agree with its comment,
2) The linked-to element is sch:schema
however the parent of the include
is not a schema. In this case, it is an
error. (Actually, it should
be an error for other kinds of containment
problems, but we won't
check for them in this version.)
It does not agree because the test above does not check whether the
parent of the include is a schema.
When I change the above test to
test=" ($theFragment_2/self::iso:schema
and not(parent::iso:schema))
or $theContainedFragments/self::iso:schema"
it seems to work more as designed.
Also, I had to insert another case before case 3 to handle the
experimental include-children feature; otherwise, case 3 would copy the
included <iso:schema> element.
<!-- If this were XLST 2, we could use
if ($theFragment) then $theFragment else
$theContainedFragments
here (thanks to KN)
-->
<!-- case 2a - LAH -->
<xsl:when test="name(..) =
name($theFragment_2)">
<xsl:apply-templates
select="$theContainedFragments"
mode="dsdl:go" />
</xsl:when>
<!-- case 3 -->
<xsl:otherwise>
<xsl:apply-templates
select="$theFragment_2"
mode="dsdl:go" />
</xsl:otherwise>
Thus modified, the experimental include behavior works as described.
Have I missed something in how it's supposed to be used, that's
preventing it from working for me in the form that I downloaded it?
Otherwise, the above is offered as a patch.
On a somewhat related note, iso_dsdl_include.xsl has a comment that says,
Limitations:
* No rebasing: relative paths will be interpreted based on the
initial document's
path, not the including document. (Severe limitation!)
I would like to add my vote for the ability to "rebase." In our
environment, it is indeed a severe limitation. As far as I can tell,
iso_dsdl_include.xsl uses the base URL of the input schema, which in our
case is not useful.
Ideally, I'd like to be able to pass in a parameter to
iso_dsdl_include.xsl which I can use as a base URL for resolving the href.
Second best would be the ability (e.g. a boolean attribute) to specify
that I want to use the iso_dsdl_include.xsl stylesheet's base URL as the
base for resolving the <iso:include>/@href.
Regards,
Lars
On 6/24/2010 10:59 AM, Lars Huttar wrote:
> Hello,
> Is there a way in ISO schematron to include a set of keys?
> Suppose I need several schematron schemas that use a common set of keys...
> <xsl:key name="key1" ...
> <xsl:key name="key2" ...
> etc.
>
> My understanding so far is:
> - (1) The <iso:include> element "references an external well-formed
> XML document whose document element is a Schematron element of a type
> which allowed by the grammar for Schematron at the current position in
> the schema." Thus
> - (a) the included file cannot be an XML document fragment, e.g. a
> series of <xsl:key> elements; it could only be a single <xsl:key>, or
> some element whose children are <xsl:key>s.
> - (b) the document element of the included document cannot be
> <xsl:key> because it must be "a Schematron element" ... I'm not
> positive whether this term actually excludes "foreign" elements. The
> spec says that a grammar for "Schematron elements" is given in Annex
> A, which gives a RelaxNG schema that allows "foreign" elements. If the
> document element of the included document cannot be <xsl:key>, then
> apparently we cannot include even one key per included file.
> - (2) The spec says that xsl:key can only be included before the
> pattern element, and from the RelaxNG schema for Schematron, this
> seems to imply that xsl:key cannot be contained in any container
> element that could be included.
>
> So from this I conclude that the only way to include keys from
> external files is to put one <xsl:key> in each external file, then
> include each external file with a <iso:include> element in each
> including schema.
> With that overhead - an extra file and an extra include per key - I'm
> not sure that there's any net benefit in using an include versus
> duplicating each <xsl:key> in each schema that needs them.
>
> Is there a better way to include a common set of keys, that I'm missing?
>
> Thanks,
> Lars
>
>
>
> _______________________________________________
> Schematron mailing list
> Schematron at eccnet.com
> http://www.eccnet.com/mailman/listinfo/schematron
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.eccnet.com/pipermail/schematron/attachments/20100706/0edb0ff0/attachment.html
More information about the Schematron
mailing list