Re: [xsl] RE: Best way to represent an item and its context?

Subject: Re: [xsl] RE: Best way to represent an item and its context?
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Sat, 17 Sep 2011 22:26:55 +0100
On 17/09/2011 20:01, Costello, Roger L. wrote:
Hi Folks,

Many thanks for the responses.

Please allow me to provide more insight into what I am doing and inquire why I am getting an "ArrayIndexOutOfBoundsException" with Saxon.
That's a bug, plain and simple. It's caused, I think, by the fact that Saxon is treating the XSD namespace specially, but you are using it in your stylesheet as just-another-namespace (as you are perfectly entitled to do). I'll investigate it and fix it. The preferred way to report Saxon bugs is on the saxon-help list at SourceForge.

Michael Kay
Saxonica


Recall that an XML Schema may be imported or included by another XML Schema. That importing/including schema is the "context" for the schema. Further, there may be a schema that imports/includes the importing/including schema and is its context. And so on.


I'd like to represent a schema in its context, i.e., a "schema-in-context".

Here are two simple functions to do it. The first function takes a schema and creates a schema-in-context that has an empty context. The second takes a schema and its context.

     <xsl:function name="sic:schema-in-context">
         <xsl:param name="schema" as="element()"/>

         <schema-in-context>
             <schema><xsl:sequence select="$schema" /></schema>
             <schema-in-context />
         </schema-in-context>

</xsl:function>

     <xsl:function name="sic:schema-in-context">
         <xsl:param name="schema" as="element()"/>
         <xsl:param name="schema-in-context" as="element()"/>

         <schema-in-context>
             <schema><xsl:sequence select="$schema" /></schema>
             <xsl:sequence select="$schema-in-context" />
         </schema-in-context>
     </xsl:function>

Do you see anything wrong with those? Apparently there is something wrong, since I get an "ArrayIndexOutOfBoundsException" with Saxon, as I describe next.

Here's a variable consisting of three schemas:

             <xsl:variable name="schemas">
                 <schemas>
                     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
                                             targetNamespace="http://www.test.org";
                                             xmlns="http://www.test.org";
                                            elementFormDefault="qualified">

<xsd:include schemaLocation="schema2.xsd" />

                         <xsd:element name="Title" type="xsd:string" />
                         <xsd:element name="Author" type="Author" />

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

<xsd:include schemaLocation="schema3.xsd" />

                         <xsd:simpleType name="Author">
                             <xsd:restriction base="xsd:string">
                                 <xsd:maxLength value="20" />
                             </xsd:restriction>
                         </xsd:simpleType>

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

<xsd:element name="Date" type="xsd:date" />

                     </xsd:schema>
                 </schemas>
             </xsl:variable>

I obtain the first schema and invoke the schema-in-context function with it:

<xsl:variable name="schema-in-context-1" select="sic:schema-in-context($schemas/schemas/xs:schema[1])" />

             <Test1>
                 <xsl:sequence select="$schema-in-context-1" />
             </Test1>

The output is perfect.

I obtain the second schema and invoke the schema-in-context function with it and $schema-in-context-1:

<xsl:variable name="schema-in-context-2" select="sic:schema-in-context($schemas/schemas/xs:schema[2], $schema-in-context-1)" />

             <Test2>
                 <xsl:sequence select="$schema-in-context-2" />
             </Test2>

Again, the output is perfect.

Now, things go bad. I obtain the third schema and invoke the schema-in-context function with it and $schema-in-context-2:

<xsl:variable name="schema-in-context-3" select="sic:schema-in-context($schemas/schemas/xs:schema[3], $schema-in-context-2)" />

             <Test3>
                 <xsl:sequence select="$schema-in-context-3" />
             </Test3>

I get this exception:

java.lang.ArrayIndexOutOfBoundsException: -1
         at net.sf.saxon.om.NamePool.getPrefixFromNamespaceCode(NamePool.java:937)
         at net.sf.saxon.serialize.XMLEmitter.namespace(XMLEmitter.java:369)
         at net.sf.saxon.event.ProxyReceiver.namespace(ProxyReceiver.java:140)
         at net.sf.saxon.event.NamespaceReducer.namespace(NamespaceReducer.java:122)
         at net.sf.saxon.event.ComplexContentOutputter.startContent(ComplexContentOutputter.java:571)
         at net.sf.saxon.event.ComplexContentOutputter.startElement(ComplexContentOutputter.java:180)
         at net.sf.saxon.tree.tiny.TinyElementImpl.copy(TinyElementImpl.java:312)

         at net.sf.saxon.event.ComplexContentOutputter.append(ComplexContentOutputter.java:521)
         at net.sf.saxon.expr.Expression.process(Expression.java:490)
         at net.sf.saxon.expr.CardinalityChecker.process(CardinalityChecker.java:268)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:318)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:269)
         at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:569)
         at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:123)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:318)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:269)
         at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:123)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:318)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:269)
         at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:569)
         at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:567)
         at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:569)
         at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:123)
         at net.sf.saxon.expr.LetExpression.process(LetExpression.java:409)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:318)
         at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:269)
         at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:208)
         at net.sf.saxon.expr.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:368)
         at net.sf.saxon.Controller.transformDocument(Controller.java:1887)
         at net.sf.saxon.Controller.transform(Controller.java:1737)
         at net.sf.saxon.Transform.processFile(Transform.java:938)
         at net.sf.saxon.Transform.doTransform(Transform.java:572)
         at net.sf.saxon.Transform.main(Transform.java:72)
Fatal error during transformation: java.lang.ArrayIndexOutOfBoundsException: -1

After much effort I am unable to determine what the problem is. Any help you could provide would be much appreciated. Below is the complete stylesheet.

/Roger

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                            xmlns:xs="http://www.w3.org/2001/XMLSchema";
                            xmlns:sic="http://www.schema-library.org/schema-in-context";
                           version="2.0">

     <xsl:function name="sic:schema-in-context">
         <xsl:param name="schema" as="element()"/>

         <schema-in-context>
             <schema><xsl:sequence select="$schema" /></schema>
             <schema-in-context />
         </schema-in-context>

</xsl:function>

     <xsl:function name="sic:schema-in-context">
         <xsl:param name="schema" as="element()"/>
         <xsl:param name="schema-in-context" as="element()"/>

         <schema-in-context>
             <schema><xsl:sequence select="$schema" /></schema>
             <xsl:sequence select="$schema-in-context" />
         </schema-in-context>
     </xsl:function>

     <xsl:template match="/">
         <Results>

             <xsl:variable name="schemas">
                 <schemas>
                     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema";
                                             targetNamespace="http://www.test.org";
                                             xmlns="http://www.test.org";
                                            elementFormDefault="qualified">

<xsd:include schemaLocation="schema2.xsd" />

                         <xsd:element name="Title" type="xsd:string" />
                         <xsd:element name="Author" type="Author" />

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

<xsd:include schemaLocation="schema3.xsd" />

                         <xsd:simpleType name="Author">
                             <xsd:restriction base="xsd:string">
                                 <xsd:maxLength value="20" />
                             </xsd:restriction>
                         </xsd:simpleType>

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

<xsd:element name="Date" type="xsd:date" />

                     </xsd:schema>
                 </schemas>
             </xsl:variable>

<xsl:variable name="schema-in-context-1" select="sic:schema-in-context($schemas/schemas/xs:schema[1])" />

             <Test1>
                 <xsl:sequence select="$schema-in-context-1" />
             </Test1>

<xsl:variable name="schema-in-context-2" select="sic:schema-in-context($schemas/schemas/xs:schema[2], $schema-in-context-1)" />

             <Test2>
                 <xsl:sequence select="$schema-in-context-2" />
             </Test2>

<xsl:variable name="schema-in-context-3" select="sic:schema-in-context($schemas/schemas/xs:schema[3], $schema-in-context-2)" />

             <Test3>
                 <xsl:sequence select="$schema-in-context-3" />
             </Test3>

         </Results>
     </xsl:template>

</xsl:stylesheet>

Current Thread