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 |