Thursday, February 24, 2022
XML Schema 1.1 : <assertion> facet with attribute "fixed"
Saturday, January 29, 2022
XML Schema 1.1 : conditional inclusion
Tuesday, January 18, 2022
XML Schema 1.1 : using regex
Wednesday, June 9, 2021
XML Schema xsi:type and xs:alternative
After having studied little bit deeply about XML Schema's xsi:type attribute, and xs:alternative (introduced in the XML Schema 1.1 version) element, I've come to conclusion that, there are lot of functional similarities between xsi:type and xs:alternative, and of course differences as well. To illustrate these points, I've come up with following XML Schema and XML document instance examples (that I shall also attempt to explain within this blog post).
XML Schema document 1 (conforming to XSD 1.1)
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="note" type="NoteType"/>
<xs:complexType name="NoteType">
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NoteType2">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="NoteType3">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
<xs:assert test="to castable as emailAddress"/>
<xs:assert test="from castable as emailAddress"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="emailAddress">
<xs:restriction base="xs:string">
<xs:pattern value="[^@]+@[^@\.]+(\.[^@\.]+)+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Following are three XML document instances, that are valid with above specified XML Schema document:
XML document instance 1
<note>
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
XML document instance 2
<note isConfidential="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="NoteType2">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
XML document instance 3
<note isConfidential="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="NoteType3">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
The "XML document instance 1", is an XML document that is valid according to an XSD element declaration and an XSD type definition "NoteType".
The "XML document instance 2" asserts that the type of an XML instance element "note" must be "NoteType2".
The "XML document instance 3" asserts that the type of an XML instance element "note" must be "NoteType3".
Note that, as per XML Schema language, the XSD type named as a value of xsi:type attribute, must be validly substitutable for the declared type (i.e, which is associated within an XML schema) of an XML element. According to the XML Schema language, a type S is validly substitutable for type T, if type S is a type derived from type T.
Now consider another XML Schema document, as following,
XML Schema document 2 (conforming to XSD 1.1)
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="note" type="NoteType">
<xs:alternative test="@noteType2 = true()" type="NoteType2"/>
<xs:alternative test="@noteType3 = true()" type="NoteType3"/>
</xs:element>
<xs:complexType name="NoteType">
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NoteType2">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
<xs:attribute name="noteType2" type="xs:boolean" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="NoteType3">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
<xs:attribute name="noteType3" type="xs:boolean" use="required"/>
<xs:assert test="to castable as emailAddress"/>
<xs:assert test="from castable as emailAddress"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="emailAddress">
<xs:restriction base="xs:string">
<xs:pattern value="[^@]+@[^@\.]+(\.[^@\.]+)+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Following are two XML document instances, that are valid with above specified XML Schema document:
XML document instance 4
<note isConfidential="true" noteType2="true">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
XML document instance 5
<note isConfidential="true" noteType3="true">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
I think that, XML Schema documents 1 and 2 as illustrated in examples above, solve the same XML document validation problem, but in two different ways. With XSD element xs:alternative, we need to introduce a new physical XML attribute like "noteType2" & "noteType3", whereas we can achieve the same effect using an attribute xsi:type with another solution.
Following is another XML Schema 1.1 document, that has a little variation than the XML Schema document "XML Schema document 2" specified earlier above,
XML Schema document 3
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="note" type="NoteType">
<xs:alternative test="@noteType = 2" type="NoteType2"/>
<xs:alternative test="@noteType = 3" type="NoteType3"/>
</xs:element>
<xs:complexType name="NoteType">
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NoteType2">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
<xs:attribute name="noteType" type="NoteTypeVal" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="NoteType3">
<xs:complexContent>
<xs:extension base="NoteType">
<xs:attribute name="isConfidential" type="xs:boolean" use="required"/>
<xs:attribute name="noteType" type="NoteTypeVal" use="required"/>
<xs:assert test="to castable as emailAddress"/>
<xs:assert test="from castable as emailAddress"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="emailAddress">
<xs:restriction base="xs:string">
<xs:pattern value="[^@]+@[^@\.]+(\.[^@\.]+)+"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="NoteTypeVal">
<xs:restriction base="xs:positiveInteger">
<xs:minInclusive value="2"/>
<xs:maxInclusive value="3"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Two valid XML instance documents, with the above mentioned XML Schema document are following,
<note isConfidential="true" noteType="2">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
<note isConfidential="true" noteType="3">
<to>abc.pqr@gmail.com</to>
<from>no-reply@gmail.com</from>
<heading>hi</heading>
<body>this is test</body>
</note>
With the XML Schema document "XML Schema document 3" specified above, we've defined an attribute "noteType" for both the types "NoteType2" and "NoteType3". We distinguish within the XML instance document, with which XSD type the "note" element would be validated, by the value of attribute "noteType" within the XML instance document.
Also note that, as per XML Schema 1.1 specification for type alternatives (i.e when having xs:alternative elements within XSD documents), the following must be applicable,
For each type T of sibling xs:alternative elements within an XSD document, type T must be validly derived from an element's default type definition (this is a constraint similar to those for xsi:type), or T can be type xs:error.
Sunday, May 3, 2020
Online XML Schema validation service
The mentioned 'online XML Schema validation service', also provides REST APIs to be invoked from any program that can issue HTTP POST requests. The 'online XML Schema validation service' referred above, provides downloadable examples written in Python and C# that use the provided REST APIs. The responses from mentioned REST APIs can be in following formats: XML, JSON, plain text (the REST API response format, can be set while issuing HTTP requests).
Interestingly, I've discovered that, the above mentioned REST APIs can be invoked directly via a tool like curl by using its platform binary. With modern computer OSs (for e.g, Windows 10), curl comes pre-installed within the OS. Following are network responses on the command line, for the few curl requests that I issued to the mentioned REST APIs,
curl --form xmlFile=@two_inp_files/x1_valid_1.xml --form xsdFile1=@two_inp_files/x1.xsd --form ver=1.1 --form xsd11CtaFullXPath=no --form responseType=xml https://www.softwarebytes.org/xmlvalidation/api/xsValidationHandler
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<validationReport>
<xsdVer>1.1</xsdVer>
<success>
<message>XML document is assessed as valid with the XSD document(s) that were provided.</message>
</success>
</validationReport>
curl --form xmlFile=@two_inp_files/x1_invalid_1.xml --form xsdFile1=@two_inp_files/x1.xsd --form ver=1.1 --form xsd11CtaFullXPath=no --form responseType=xml https://www.softwarebytes.org/xmlvalidation/api/xsValidationHandler
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<validationReport>
<xsdVer>1.1</xsdVer>
<failure>
<message>XML document is assessed as invalid with the XSD document(s) that were provided.</message>
<details>
<detail_1>[Error] x1_invalid_1.xml:3:5:cvc-assertion: Assertion evaluation ('if (@isB = true()) then b else not(b)') for element 'X' on schema type '#AnonType_X' did not succeed.</detail_1>
</details>
</failure>
</validationReport>
curl --form xmlFile=@two_inp_files/x1_valid_1.xml --form xsdFile1=@two_inp_files/x1.xsd --form ver=1.1 --form xsd11CtaFullXPath=no --form responseType=json https://www.softwarebytes.org/xmlvalidation/api/xsValidationHandler
{
"xsdVer": "1.1",
"success": {"message": "XML document is assessed as valid with the XSD document(s) that were provided."}
}
curl --form xmlFile=@two_inp_files/x1_invalid_1.xml --form xsdFile1=@two_inp_files/x1.xsd --form ver=1.1 --form xsd11CtaFullXPath=no --form responseType=json https://www.softwarebytes.org/xmlvalidation/api/xsValidationHandler
{
"xsdVer": "1.1",
"failure": {
"details": ["[Error] x1_invalid_1.xml:3:5:cvc-assertion: Assertion evaluation ('if (@isB = true()) then b else not(b)') for element 'X' on schema type '#AnonType_X' did not succeed."],
"message": "XML document is assessed as invalid with the XSD document(s) that were provided."
}
}
The mentioned 'online XML Schema validation service', supports both 1.0 and 1.1 versions of XML Schema language.
Wednesday, April 15, 2020
RDBMS, Message queue, Message broker, ESB, HTTP (technology comparison)
Unlike message queue, both message broker and ESB allow selective routing and transformation of the messages between applications (where routing and message transformation decisions take place at the message broker or on an ESB node).
The following site provides a nice documentation about how to build messaging applications: https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.0.0/com.ibm.mq.dev.doc/q022830_.htm.
5) HTTP: As good as it was when it was introduced, the HTTP protocol and its implementations within web browsers and various programming libraries is a very good means to establish software application integration. An HTTP server can respond with information and can perform actions, as asked by the HTTP clients. For various needs these days, HTTP servers can respond with information stored within the HTTP server itself, or HTTP servers can interface with other backend systems like databases and fetch information from them or modify those information as asked by HTTP clients.
It is useful to know that, HTTP style of software application integration is inherently synchronous in nature (i.e, application clients keep waiting at the point of issuing a request until a response is received), while all other styles of application integration mentioned in this blog post are inherently asynchronous (i.e application clients can start doing something else after issuing a request and before getting a response).
Saturday, March 21, 2020
Using XML Schema 1.1 <alternative> with Xerces-J
The XSD 1.1 specification, defines a particular subset of XPath 2.0 language that can be used as value of 'test' attribute of XSD 1.1 <alternative> element. The XSD 1.1 language's XPath 2.0 subset is much smaller than the whole XPath 2.0 language. The specification of this smaller CTA XPath subset, can be read at https://www.w3.org/TR/xmlschema11-1/#coss-ta (specifically, the section mentioning '2.1 It conforms to the following extended BNF' which has grammar specification for the CTA XPath subset).
In fact, the XSD 1.1 specification allows XSD validators, implementing XSD 1.1's <alternative> element, to support a bigger set of XPath 2.0's features (commonly the full XPath 2.0 language) than what is defined by XSD 1.1 CTA (conditional type alternatives) XPath subset.
For XSD 1.1 CTAs, Xerces-J with user option, allows selecting either:
1) The smaller XPath subset (the default for Xerces-J), or
2) Full XPath 2.0. How selecting between XPath subset or the full XPath 2.0 language, can be done for Xerces-J's CTA implementation is described here, https://xerces.apache.org/xerces2-j/faq-xs.html#faq-3.
I've analyzed a bit, the nature of XSD 1.1 CTA XPath subset language. Following are essentially the main XSD 1.1 CTA XPath subset patterns, that may be used within XSD 1.1 schemas when using XSD <alternative> element,
1) Using comparators (like >, <, =, !=, <=, >=):
The example CTA XPath expressions are following,
@x = @y,
@x = 3,
@x != 3,
@x > @y
2) Using comparators with logical operators:
The example CTA XPath expressions are following,
(@x = @y) or (@p = @q),
((1 = 2) or (5 = 6)) and (5 = 7),
(1 and 2) or (5 and 7)
3) Using XPath 2.0 'not' function:
An example XPath expression is following,
(@x = @y) and not(@p)
Interestingly, the XSD 1.1 CTA XPath subset language, allows using only the XPath 2.0 fn:not function and no other XPath 2.0 built-in functions. Constructor functions, for all built-in XSD types may be used, for e.g xs:integer(..), xs:boolean(..) etc, in XSD 1.1 CTA XPath subset expressions.
As per the XSD 1.1 specification, during XSD 1.1 CTA evaluations, the XML element and attribute nodes are untyped (i.e the XML nodes do not carry any type annotation coming from a XML schema). Therefore, in many cases, XSD 1.1 CTA XPath subset expressions when used with Xerces-J need to use explicit casts (for e.g, <xs:alternative test="(xs:integer(@x) = xs:integer(@y)) and fn:not(xs:boolean(@p))"> with namespace prefix 'fn' bound to the URI 'http://www.w3.org/2005/xpath-functions'). For the CTA XPath subset language or the full XPath 2.0 language for CTAs, it is optional for the XPath expressions to have the "fn" prefix with the XPath built-in functions. Typically, XML schema authors would not use the "fn" prefix for XPath built-in functions.