Xpath result vs. xs:assert result
This should cover W3C XML Schema, Relax NG and DTD related problems.
Xpath result vs. xs:assert result
XML Editor 16.1 using SaxonEE set for XML Schema 1.1
I want to insure that elements in a complexType that is a restriction of a base complexType, have the same number of enumerations. (Code below)
The sample below should fail this assert:
because assignor has three enumerations and the other elements have two. Whether I put this in the base complexType or the restricted complexType it still shows the restriction as a valid schema.
If I execute this
in the XPath editor it fails as expected as well as passes when all three have two enumerations.
Sample restriction:
Am I missing something in the assert?
Thanks.
I want to insure that elements in a complexType that is a restriction of a base complexType, have the same number of enumerations. (Code below)
The sample below should fail this assert:
Code: Select all
<xs:assert test="count(//xs:element[@name='id-name']//xs:enumeration) eq count(//xs:element[@name='issuer']//xs:enumeration)
and
count(//xs:element[@name='issuer']//xs:enumeration) eq count(//xs:element[@name='assignor']//xs:enumeration)"></xs:assert>
If I execute this
Code: Select all
count(//xs:element[@name='id-name']//xs:enumeration) eq count(//xs:element[@name='issuer']//xs:enumeration) and
count(//xs:element[@name='issuer']//xs:enumeration) eq count(//xs:element[@name='assignor']//xs:enumeration)
Sample restriction:
Code: Select all
<xs:complexType name='mytype' xml:lang='en-US'>
<xs:complexContent>
<xs:restriction base='myBaseType'>
<xs:sequence>
<xs:element maxOccurs='1' minOccurs='1' name='id-name'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='URI'></xs:enumeration>
<xs:enumeration value='ID Number'></xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element maxOccurs='1' minOccurs='1' name='issuer'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='Owner'/>
<xs:enumeration value='Owner'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element maxOccurs='1' minOccurs='1' name='assignor'>
<xs:simpleType>
<xs:restriction base='xs:string'>
<xs:enumeration value='Owner'/>
<xs:enumeration value='Owner'/>
<xs:enumeration value='Owner'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
Thanks.
Re: Xpath result vs. xs:assert result
So you want to use the xs:assert to validate your schema and not to validate the xml described by your schema, right?
In this case the xs:assert would need to be placed in the xsd describing your xsd. Since you probably don't want to extend the stadard xsd for this you could do this with an additional schematron file instead. This could look like this:
Now you have to validate your xsd file with this schematron file. Unfortunatly you can't assign the schematron to the xsd (at least for me it did not work) to validate it automatically. I tested it with
However, you could define your own document type in oxygen by deriving a new one from "xml schema". Here you can add the schematron file in the validation tab and mark it as standard validation.
Now you need to find a way to associate your xsd with this new document type rather then the original xsml schema. For testing purpose I simply used the file name of the xsd as association rule. (A "real" solution would probably require a java class to identifier the document type - that's at least what I'm planing to do for the extended validtion of my ofn xsd files.)
When you makred document type as a higher priority than the original one you should get following message in your example when validating it:
Patrik
In this case the xs:assert would need to be placed in the xsd describing your xsd. Since you probably don't want to extend the stadard xsd for this you could do this with an additional schematron file instead. This could look like this:
Code: Select all
<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<ns uri="http://www.w3.org/2001/XMLSchema" prefix="xs"/>
<pattern>
<rule context="xs:restriction[@base = 'myBaseType']">
<let name="CountIdName" value="count(.//xs:element[@name='id-name'] //xs:enumeration)"/>
<let name="CountIssuer" value="count(.//xs:element[@name='issuer'] //xs:enumeration)"/>
<let name="CountAssignor" value="count(.//xs:element[@name='assignor']//xs:enumeration)"/>
<assert test="($CountIdName eq $CountIssuer) and ($CountIssuer = $CountAssignor)">
Number of enumerations needs to be the same for elements
id-name (<value-of select="$CountIdName"/>),
issuer (<value-of select="$CountIssuer"/>) and
assignor (<value-of select="$CountAssignor"/>).
</assert>
</rule>
</pattern>
</schema>
Code: Select all
<?xml-model href="XsdValidation.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
Now you need to find a way to associate your xsd with this new document type rather then the original xsml schema. For testing purpose I simply used the file name of the xsd as association rule. (A "real" solution would probably require a java class to identifier the document type - that's at least what I'm planing to do for the extended validtion of my ofn xsd files.)
When you makred document type as a higher priority than the original one you should get following message in your example when validating it:
Code: Select all
Number of enumerations needs to be the same for elements id-name (2), issuer (2) and assignor (3).
Re: Xpath result vs. xs:assert result
Note that you can use any xpath and call xslt function in the schematron rules. Thus, i can hardly imagine anything more flexible than that. Didn't test it but you could probably even implement a very generic schematron rule that actually evaluates an xpath expression written in the xsd. Then you could actually define rules in the xsd to be applied to itself...
Re: Xpath result vs. xs:assert result
Thanks. Your intuition is correct. You can store schematron in an appinfo section, according to this http://www.topologi.com/resources/schtrn_xsd_paper.htmlPatrik wrote:Note that you can use any xpath and call xslt function in the schematron rules. Thus, i can hardly imagine anything more flexible than that. Didn't test it but you could probably even implement a very generic schematron rule that actually evaluates an xpath expression written in the xsd. Then you could actually define rules in the xsd to be applied to itself...
So I will investigate schematron further.
Re: Xpath result vs. xs:assert result
Yes, it's possible to embed schematron rules in xsd. But youÄll have the same problem as with the xs:assert: it applies to the xsml file you're validating rather the the schema itself.
For demonstration (and fun) I implemented a simple "DerivedAssert" you can add into the xml schema that is being evaluated by a schematron file:
DerivedAssert.sch:
DerivedAssert.xsl:
Test-xsd:
Now when validation the xsd with schematron.sch the rule from within the xsd (DerivedAssert/@test) is being evaluated and you get the message "Number of enumerations needs to be the same for elements issuer assignor.".
It's quite primitive but should point to a possible direction...
For demonstration (and fun) I implemented a simple "DerivedAssert" you can add into the xml schema that is being evaluated by a schematron file:
DerivedAssert.sch:
Code: Select all
<schema xmlns="http://purl.oclc.org/dsdl/schematron" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" queryBinding="xslt2">
<ns uri="http://www.w3.org/2001/XMLSchema" prefix="xs"/>
<ns uri="derivedAssert" prefix="da"/>
<xsl:include href="DerivedAssert.xsl"/>
<pattern>
<rule context="xs:complexType/xs:complexContent/xs:restriction[@base = $DerivedAssertList/@type]">
<assert test="da:CheckAssertion(.)">
<value-of select="da:Message(.)"/>
</assert>
</rule>
</pattern>
</schema>
Code: Select all
<xsl:transform
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
xmlns:xs = "http://www.w3.org/2001/XMLSchema"
xmlns:saxon = "http://saxon.sf.net/"
xmlns:da = "derivedAssert"
exclude-result-prefixes="#all"
version="2.0">
<xsl:variable name="DerivedAssertList" as="element()*">
<xsl:apply-templates select="/" mode="DerivedAssertList"/>
</xsl:variable>
<xsl:template match="element() | document-node()" mode="DerivedAssertList">
<xsl:apply-templates select="*" mode="#current"/>
</xsl:template>
<xsl:template match="xs:complexType/xs:annotation/xs:appinfo/DerivedAssert" mode="DerivedAssertList">
<xsl:copy>
<xsl:attribute name="type" select="parent::*/parent::*/parent::*/@name"/>
<xsl:copy-of select="@test, @message"/>
</xsl:copy>
</xsl:template>
<xsl:function name="da:CheckAssertion" as="xs:boolean">
<xsl:param name="Restriction" as="element(xs:restriction)"/>
<xsl:variable name="DerivedAssert" as="element()?" select="$DerivedAssertList[$Restriction/@base = @type]"/>
<xsl:choose>
<xsl:when test="exists($DerivedAssert)">
<xsl:for-each select="$Restriction"> <!-- set context -->
<xsl:sequence select="xs:boolean(saxon:evaluate($DerivedAssert/@test))"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="true()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="da:Message" as="xs:string">
<xsl:param name="Restriction" as="element(xs:restriction)"/>
<xsl:variable name="DerivedAssert" as="element()?" select="$DerivedAssertList[$Restriction/@base = @type]"/>
<xsl:sequence select="$DerivedAssert/@message"/>
</xsl:function>
</xsl:transform>
Code: Select all
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:complexType name="myBaseType">
<xs:annotation>
<xs:appinfo>
<DerivedAssert
test = "count(.//xs:element[@name='issuer']//xs:enumeration) = count(.//xs:element[@name='assignor']//xs:enumeration)"
message = "Number of enumerations needs to be the same for elements issuer assignor."/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="issuer" type="xs:string"/>
<xs:element name="assignor" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="myType">
<xs:complexContent>
<xs:restriction base="myBaseType">
<xs:sequence>
<xs:element name="issuer">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Owner"/>
<xs:enumeration value="Owner"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="assignor">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Owner"/>
<xs:enumeration value="Owner"/>
<xs:enumeration value="Owner"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
It's quite primitive but should point to a possible direction...
Re: Xpath result vs. xs:assert result
Thanks for this Patrik.
It certainly looks like it is a start.
However, just copying the files into oXygen (saving them in the same directory) and setting a Validation scenario to use Saxon and embedded Schematron still shows a valid XSD.
I am not an oXygen guru so maybe I am missing something in the settings?
It certainly looks like it is a start.
However, just copying the files into oXygen (saving them in the same directory) and setting a Validation scenario to use Saxon and embedded Schematron still shows a valid XSD.
I am not an oXygen guru so maybe I am missing something in the settings?
Re: Xpath result vs. xs:assert result
You need to validate the Test-xsd file against the schematron file DerivedAssert.sch
Re: Xpath result vs. xs:assert result
Ahhh, duh.Patrik wrote:You need to validate the Test-xsd file against the schematron file DerivedAssert.sch
I thought the validation scenario would 'magically' load the schematron file.
But yes it works as you described and I think this will work just fine.
Cheers,
Tim
Jump to
- Oxygen XML Editor/Author/Developer
- ↳ Feature Request
- ↳ Common Problems
- ↳ DITA (Editing and Publishing DITA Content)
- ↳ SDK-API, Frameworks - Document Types
- ↳ DocBook
- ↳ TEI
- ↳ XHTML
- ↳ Other Issues
- Oxygen XML Web Author
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Content Fusion
- ↳ Feature Request
- ↳ Common Problems
- Oxygen JSON Editor
- ↳ Feature Request
- ↳ Common Problems
- Oxygen PDF Chemistry
- ↳ Feature Request
- ↳ Common Problems
- Oxygen Feedback
- ↳ Feature Request
- ↳ Common Problems
- Oxygen XML WebHelp
- ↳ Feature Request
- ↳ Common Problems
- XML
- ↳ General XML Questions
- ↳ XSLT and FOP
- ↳ XML Schemas
- ↳ XQuery
- NVDL
- ↳ General NVDL Issues
- ↳ oNVDL Related Issues
- XML Services Market
- ↳ Offer a Service