Re: [xsl] How to check an element's type against an XSD simpleType and skip that element if it does not conform to the simpleType?

Subject: Re: [xsl] How to check an element's type against an XSD simpleType and skip that element if it does not conform to the simpleType?
From: Martin Honnen <Martin.Honnen@xxxxxx>
Date: Tue, 16 Jul 2013 14:25:25 +0200
Costello, Roger L. wrote:
Michael Kay wrote:

Unfortunately schema-aware processing in XQuery and XSLT
doesn't give you this capability.

Is there a workaround?


Is there is no way for an XSLT program to express: "Hey, validate xyz against the XML Schema and if xyz is not schema-valid then discard it." No way to express that?

I think what you can do is not to validate the input XML but to import a schema and then you can write checks using e.g.
foo castable as someType
to filter out valid or invalid items.


So with AltovaXML, when I process the input

<BookStore xmlns="http://www.books.org";>
        <Book>
                <Title>My Life and Times</Title>
                <Author>Paul McCartney</Author>
                <Date>1998</Date>
                <ISBN>xxx1-56592-235-2</ISBN>
                <Publisher>McMillan Publishing</Publisher>
        </Book>
        <Book>
          <Title>Killing Time</Title>
          <ISBN>1-12345-123-1</ISBN>
        </Book>
</BookStore>

with the XSLT

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
               xmlns:bk="http://www.books.org";
               exclude-result-prefixes="bk"
               version="2.0">

<xsl:output method="xml"/>

    <xsl:import-schema namespace="http://www.books.org";
                       schema-location="test2013071602.xsd"/>

<xsl:template match="/">
<BookISBNs>
<xsl:for-each select="/bk:BookStore/bk:Book[bk:ISBN castable as bk:ISBN-type]">
<ISBN><xsl:value-of select="bk:ISBN"/></ISBN>
</xsl:for-each>
</BookISBNs>
</xsl:template>


</xsl:transform>

where the schema is

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
            targetNamespace="http://www.books.org";
            xmlns="http://www.books.org";
            elementFormDefault="qualified">

<xsd:element name="BookStore">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Book" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>


    <xsd:element name="Book">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="Title"/>
                <xsd:element ref="Author"/>
                <xsd:element ref="Date"/>
                <xsd:element ref="ISBN"/>
                <xsd:element ref="Publisher"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="Title" type="xsd:string"/>
    <xsd:element name="Author" type="xsd:string"/>
    <xsd:element name="Date" type="xsd:string"/>
    <xsd:element name="ISBN" type="ISBN-type"/>
    <xsd:element name="Publisher" type="xsd:string"/>

<xsd:simpleType name="ISBN-type">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{1}-\d{5}-\d{3}-\d{1}|\d{1}-\d{3}-\d{5}-\d{1}|\d{1}-\d{2}-\d{6}-\d{1}"/>


        </xsd:restriction>
    </xsd:simpleType>

</xsd:schema>

then I get the result

<BookISBNs><ISBN>1-12345-123-1</ISBN></BookISBNs>

So that way you can do some type checking against the schema type although the XML input you process is not being validated as a complete document.

Current Thread