[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[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: [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: "Costello, Roger L." <costello@xxxxxxxxx>
Date: Mon, 15 Jul 2013 18:55:50 +0000

Hi Folks,

I would like to do schema-aware processing on this document:

<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>
        ...
</BookStore>

I have a corresponding XML Schema, which I show in its entirety at the bottom
of this message. The item of interest, however, is its simpleType for ISBN
elements:

    <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>

I want my XSLT program to output each ISBN in the XML document. If an ISBN
does not conform to the simpleType, then I want to skip that ISBN element and
continue processing. At the bottom of this message is the XSLT in its
entirety. The item of interest, however, is this snippet:

            <xsl:for-each select="/bk:BookStore/bk:Book">
                <xsl:if test="data(bk:ISBN) instance of bk:ISBN-type">
                    <ISBN><xsl:value-of select="bk:ISBN"/></ISBN>
                </xsl:if>
            </xsl:for-each>

The for-loop iterates through each Book and checks to see if the value of its
ISBN element conforms to ISBN-type; if it doesn't conform, then it skips that
ISBN and goes to the next Book.

In the XML document shown above, the Book element has an ISBN
(xxx1-56592-235-2) that is not valid, so I expect my XSLT program to skip it.

However, that is not happening. I get this error message:

    The content "xxx1-56592-235-2" of element <ISBN> does not
    match the required simple type. Value "xxx1-56592-235-2"
    contravenes the pattern facet "\d{1}-\d{5}-\d{3}-\d{1}|\d{1}-..."
    of the type ISBN-type

What am I doing wrong please?

/Roger
-----------------------------------------------------------
       BookStore.xsl
-----------------------------------------------------------
<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="BookStore.xsd"/>

    <xsl:template match="/">
        <BookISBNs>
            <xsl:for-each select="/bk:BookStore/bk:Book">
                <xsl:if test="data(bk:ISBN) instance of bk:ISBN-type">
                    <ISBN><xsl:value-of select="bk:ISBN"/></ISBN>
                </xsl:if>
            </xsl:for-each>
        </BookISBNs>
    </xsl:template>

</xsl:transform>

-----------------------------------------------------------
       BookStore.xsd
-----------------------------------------------------------
<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>


Current Thread
Keywords