
I meant the context attribute of course. I can also silence the warning by defining a variable holding the appropriate elements and using the variable in my rules. This is what I will do in practice. It does look broken to me though. Thanks, -- Danny MacMillan Sent with [Proton Mail](https://proton.me/) secure email. ------- Original Message ------- On Monday, May 15th, 2023 at 10:36, Danny MacMillan <dm-bulk-oxygenxml@mail-eh.ca> wrote:
Hello,
Consider the following XML:
<?xml version="1.0"?> <root> <relevant> <element relevant-attribute="this attribute exists only on elements under relevant"/> </relevant> <irrelevant> <element/> </irrelevant> </root>
And the following Schematron:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map"> <ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/> <let name="some-map" value="map {}"/> <pattern> <rule context="/*/relevant/element[map:contains($some-map, @relevant-attribute)]"> <assert test="true()">Impossible</assert> </rule> </pattern> </schema>
When I validate the XML with the Schematron, Oxygen prints a warning that an empty sequence is not allowed as the second argument to map:contains, which I've determined is because it is testing the "element" elements under "irrelevant". I know this because if I add a second such element, the error prints twice. If I have 9, the error prints 9 times. But why is it testing that element? I deliberately used xpath that navigates via the parent because I want to include only elements under that parent, but it seems that it's looking at all elements, anywhere in the document, named 'element'. Is this expected?
I can silence the warning if I explicitly check for the presence of the attribute:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map"> <ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/> <let name="some-map" value="map {}"/> <pattern> <rule context="/*/relevant/element[@relevant-attribute and map:contains($some-map, @relevant-attribute)]"> <assert test="true()">Impossible</assert> </rule> </pattern> </schema>
But not if I precede the broken rule with a rule that should equivalently prevent the broken rule from firing on those elements:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt3" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://www.w3.org/2005/xpath-functions/map"> <ns prefix="map" uri="http://www.w3.org/2005/xpath-functions/map"/> <let name="some-map" value="map {}"/> <pattern> <rule context="/*/relevant/element[not(@relevant-attribute)]"> <assert test="true()">Impossible</assert> </rule> <rule context="/*/relevant/element[map:contains($some-map, @relevant-attribute)]"> <assert test="true()">Impossible</assert> </rule> </pattern> </schema> Thanks,
-- Danny MacMillan
Sent with [Proton Mail](https://proton.me/) secure email.