|
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: "Costello, Roger L." <costello@xxxxxxxxx> Date: Tue, 16 Jul 2013 12:07:58 +0000 |
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?
Here is an idea: feed into the XSLT program a BookStore XML document that is
known to be schema-valid and then in the XSLT program ignore it and instead
process BookStore-v2.xml, which is input via the document() function. Below is
my attempt at this. I no longer get an error, but it doesn't give the correct
results; it just gives an empty root element (<BookISBNs/> ) Any suggestions?
---------------------------------------------------------------
Roger's Brilliant Workaround BookStore.xsl
(doesn't work as desired)
---------------------------------------------------------------
<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:variable name="new-BookStore" select="document('BookStore-v2.xml')"
/>
<xsl:import-schema namespace="http://www.books.org"
schema-location="BookStore.xsd"/>
<xsl:template match="/">
<BookISBNs>
<xsl:for-each
select="$new-BookStore/bk:BookStore/bk:Book/bk:ISBN/text()">
<xsl:if test=". instance of bk:ISBN-type">
<ISBN><xsl:value-of select="."/></ISBN>
</xsl:if>
</xsl:for-each>
</BookISBNs>
</xsl:template>
</xsl:transform>
-----Original Message-----
From: Michael Kay [mailto:mike@xxxxxxxxxxxx]
Sent: Tuesday, July 16, 2013 5:49 AM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
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?
Unfortunately schema-aware processing in XQuery and XSLT doesn't give you this
capability. XSLT doesn't have the capability to process a PSVI that contains a
mix of valid and marked-as-invalid elements. It would be nice if it did, and
perhaps that's something for me to explore as a Saxon extension.
Michael Kay
Saxonica
On 15 Jul 2013, at 19:55, Costello, Roger L. wrote:
> 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 |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] How to check an element's, Michael Kay | Thread | Re: [xsl] How to check an element's, Martin Honnen |
| Re: [xsl] How to check an element's, Michael Kay | Date | Re: [xsl] How to check an element's, Martin Honnen |
| Month |