A bug methinks. To barf or not to barf. That is the question.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

A bug methinks. To barf or not to barf. That is the question.

Ihe Onwuka-2
Since I have managed to cut both the code and data down to a
manageable size I can post this to the list.

NOTA BENE

This is neither a complete stylesheet nor complete data - just enough
to expose the issue I am reporting.

Here is the data.

<?xml version="1.0"?>
<reXML xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="1.5.1">
  <InputAssumptions>
    <LeaseData>
      <Leases>
        <Lease LeaseReference="758">
          <RentalIncome>
            <BaseRent>
              <BaseRentEntry>
                <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
                <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
              </BaseRentEntry>
            </BaseRent>
          </RentalIncome>
          <FreeRents>
            <FreeRent>
              <EffectiveDate RelativeTo="Absolute">1995-11-01</EffectiveDate>
              <MonthlyAmounts>4472</MonthlyAmounts>
            </FreeRent>
          </FreeRents>
        </Lease>
      </Leases>
    </LeaseData>
  </InputAssumptions>
</reXML>

Here is the stylesheet stripped down to the bug exposing behaviour.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="xs" version="2.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes" method="html" />
  <xsl:key name="rents" match="BaseRentEntry | FreeRents/FreeRent"
use="concat(EffectiveDate,ancestor::Lease/@LeaseReference)"/>

  <xsl:template match="reXML">
      <xsl:apply-templates select="InputAssumptions"/>
  </xsl:template>

  <xsl:template match="InputAssumptions">
    <div>
      <xsl:apply-templates select="LeaseData"/>
    </div>
  </xsl:template>

  <xsl:template match="Lease">
     <xsl:apply-templates select="RentalIncome"/>
  </xsl:template>

  <xsl:template match="amounts/EffectiveDate"/>

  <xsl:template match="EffectiveDate">
    <xsl:variable name="key"
select="concat(.,ancestor::Lease/@LeaseReference)"/>
    <xsl:variable name="rentAmount"
select="key('rents',$key)[self::BaseRentEntry]/RentAmount"/>
    <xsl:variable name="freeRent"
select="key('rents',$key)[self::FreeRent]/MonthlyAmounts"/>
    <xsl:variable name="amounts" as="element()">
      <amounts>
        <xsl:sequence select=".,$rentAmount,$freeRent"/>
      </amounts>
    </xsl:variable>
    <tr>
      <td><xsl:apply-templates/></td>
      <td><xsl:apply-templates select="$rentAmount"/></td>
      <td><xsl:apply-templates select="$freeRent"/></td>
      <td><xsl:apply-templates select="$amounts"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

The above stylesheet will run without error.

Now change the xsl:sequence command in the EffectiveDate template like so.

<xsl:sequence select="parent::*,.,$rentAmount,$freeRent"/>

that is I added the parent node to the select (it doesn't have to be
the parent node... I think anything on the ancestor axis will do it).

Now Saxon is barfing errors (see the end of the post).

I'm not concerned about how to make the errors go away - already done
that (wrap the variable declared in xsl:document) and the full
stylesheet is producing the desired results.

My question is why should the inclusion of that node in that select
statement be the difference between barfing and not barfing. The
resolution of the problem does not seem to be related in any way to
what it reported. If anything I would say that it should have but did
not report an error when the on the version that did not include the
parent node .

Error on line 29 of test.xsl:
  XTDE1270: In the key() function, the node supplied in the third
argument (or the context
  node if absent) must be in a tree whose root is a document node
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#40)
     processing amounts
  in built-in template rule
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#22)
     processing
/reXML/InputAssumptions[1]/LeaseData[1]/Leases[1]/Lease[1]/RentalIncome[1]
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#17)
     processing /reXML/InputAssumptions[1]/LeaseData[1]
  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#12)
     processing /reXML/InputAssumptions[1]
  in built-in template rule
Transformation failed: Run-time errors were reported

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: A bug methinks. To barf or not to barf. That is the question.

Michael Kay
It's clear to me why it's failing; it's not yet clear to me why it doesn't fail if you remove the "parent::*" from the expression.

The XTDE1270 arises because you are using the key() function when the context item is a node in a tree whose root is not a document node. Specifically, the context item is an <EffectiveDate> element in a tree whose root is an <amounts> element. When you process the EffectiveDate element in the source document, it is processed successfully; during processing you create the variable $amounts, which is a tree rooted at an <amounts> element, and you then apply-templates to this element, which causes recursive invocation of the EffectiveDate template rule, this time applied to an element in a temporary tree with no document node. This much is all apparent from the stack trace:

  XTDE1270: In the key() function, the node supplied in the third argument (or the context
  node if absent) must be in a tree whose root is a document node
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/Users/mike/Desktop/temp/test.xsl#44)
     processing amounts
  in built-in template rule
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/Users/mike/Desktop/temp/test.xsl#23)
     processing /reXML/InputAssumptions[1]/LeaseData[1]/Leases[1]/Lease[1]/RentalIncome[1]
  in built-in template rule
  in built-in template rule
  at xsl:apply-templates (file:/Users/mike/Desktop/temp/test.xsl#18)
     processing /reXML/InputAssumptions[1]/LeaseData[1]
  at xsl:apply-templates (file:/Users/mike/Desktop/temp/test.xsl#13)
     processing /reXML/InputAssumptions[1]
  in built-in template rule

(The rule that key() only works if you have a document node is arguably poor design in the spec; it's a rule that breaks orthogonality, isn't logically necessary, and was probably put there for the convenience of implementors, which is usually a bad decision. But that's the way the spec is, and we have to live with it.)

I'm now going to explore why it doesn't fail in the absence of the parent::*.

Michael Kay
Saxonica


On 24 Mar 2014, at 09:09, Ihe Onwuka <[hidden email]> wrote:

> Since I have managed to cut both the code and data down to a
> manageable size I can post this to the list.
>
> NOTA BENE
>
> This is neither a complete stylesheet nor complete data - just enough
> to expose the issue I am reporting.
>
> Here is the data.
>
> <?xml version="1.0"?>
> <reXML xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="1.5.1">
>  <InputAssumptions>
>    <LeaseData>
>      <Leases>
>        <Lease LeaseReference="758">
>          <RentalIncome>
>            <BaseRent>
>              <BaseRentEntry>
>                <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
>                <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
>              </BaseRentEntry>
>            </BaseRent>
>          </RentalIncome>
>          <FreeRents>
>            <FreeRent>
>              <EffectiveDate RelativeTo="Absolute">1995-11-01</EffectiveDate>
>              <MonthlyAmounts>4472</MonthlyAmounts>
>            </FreeRent>
>          </FreeRents>
>        </Lease>
>      </Leases>
>    </LeaseData>
>  </InputAssumptions>
> </reXML>
>
> Here is the stylesheet stripped down to the bug exposing behaviour.
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet
>        xmlns:xs="http://www.w3.org/2001/XMLSchema"
>        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>    exclude-result-prefixes="xs" version="2.0">
>
>  <xsl:strip-space elements="*"/>
>  <xsl:output indent="yes" method="html" />
>  <xsl:key name="rents" match="BaseRentEntry | FreeRents/FreeRent"
> use="concat(EffectiveDate,ancestor::Lease/@LeaseReference)"/>
>
>  <xsl:template match="reXML">
>      <xsl:apply-templates select="InputAssumptions"/>
>  </xsl:template>
>
>  <xsl:template match="InputAssumptions">
>    <div>
>      <xsl:apply-templates select="LeaseData"/>
>    </div>
>  </xsl:template>
>
>  <xsl:template match="Lease">
>     <xsl:apply-templates select="RentalIncome"/>
>  </xsl:template>
>
>  <xsl:template match="amounts/EffectiveDate"/>
>
>  <xsl:template match="EffectiveDate">
>    <xsl:variable name="key"
> select="concat(.,ancestor::Lease/@LeaseReference)"/>
>    <xsl:variable name="rentAmount"
> select="key('rents',$key)[self::BaseRentEntry]/RentAmount"/>
>    <xsl:variable name="freeRent"
> select="key('rents',$key)[self::FreeRent]/MonthlyAmounts"/>
>    <xsl:variable name="amounts" as="element()">
>      <amounts>
>        <xsl:sequence select=".,$rentAmount,$freeRent"/>
>      </amounts>
>    </xsl:variable>
>    <tr>
>      <td><xsl:apply-templates/></td>
>      <td><xsl:apply-templates select="$rentAmount"/></td>
>      <td><xsl:apply-templates select="$freeRent"/></td>
>      <td><xsl:apply-templates select="$amounts"/></td>
>    </tr>
>  </xsl:template>
>
> </xsl:stylesheet>
>
> The above stylesheet will run without error.
>
> Now change the xsl:sequence command in the EffectiveDate template like so.
>
> <xsl:sequence select="parent::*,.,$rentAmount,$freeRent"/>
>
> that is I added the parent node to the select (it doesn't have to be
> the parent node... I think anything on the ancestor axis will do it).
>
> Now Saxon is barfing errors (see the end of the post).
>
> I'm not concerned about how to make the errors go away - already done
> that (wrap the variable declared in xsl:document) and the full
> stylesheet is producing the desired results.
>
> My question is why should the inclusion of that node in that select
> statement be the difference between barfing and not barfing. The
> resolution of the problem does not seem to be related in any way to
> what it reported. If anything I would say that it should have but did
> not report an error when the on the version that did not include the
> parent node .
>
> Error on line 29 of test.xsl:
>  XTDE1270: In the key() function, the node supplied in the third
> argument (or the context
>  node if absent) must be in a tree whose root is a document node
>  in built-in template rule
>  in built-in template rule
>  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#40)
>     processing amounts
>  in built-in template rule
>  in built-in template rule
>  in built-in template rule
>  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#22)
>     processing
> /reXML/InputAssumptions[1]/LeaseData[1]/Leases[1]/Lease[1]/RentalIncome[1]
>  in built-in template rule
>  in built-in template rule
>  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#17)
>     processing /reXML/InputAssumptions[1]/LeaseData[1]
>  at xsl:apply-templates (file:/home/ihe/22Capital/test.xsl#12)
>     processing /reXML/InputAssumptions[1]
>  in built-in template rule
> Transformation failed: Run-time errors were reported
>
> ------------------------------------------------------------------------------
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/13534_NeoTech
> _______________________________________________
> saxon-help mailing list archived at http://saxon.markmail.org/
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/saxon-help 


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: A bug methinks. To barf or not to barf. That is the question.

Michael Kay
>
> I'm now going to explore why it doesn't fail in the absence of the parent::*.
>

Adding an xsl:message shows that in the absence of the parent::*, the $amounts variable is like this (I've removed unnecessary namespaces and added indentation)

<amounts>
  <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
  <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
</amounts>

This doesn't cause recursive invocation of the EffectiveDate template because you have a higher-priority rule matching amounts/EffectiveDate.

With parent::* added back in, the variable is now:

<amounts>
  <BaseRentEntry>
    <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
    <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
  </BaseRentEntry>
  <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
  <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
</amounts>

And the first EffectiveDate element causes the recursive invocation, because it doesn't match amounts/EffectiveDate.

So, no bug: Saxon is getting it right in both cases.

Michael Kay
Saxonica



------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: A bug methinks. To barf or not to barf. That is the question.

Ihe Onwuka-2
In reply to this post by Michael Kay
On Mon, Mar 24, 2014 at 9:52 AM, Michael Kay <[hidden email]> wrote:
> It's clear to me why it's failing; it's not yet clear to me why it doesn't fail if you remove the "parent::*" from the expression.
>
>
> (The rule that key() only works if you have a document node is arguably poor design in the spec; it's a rule that breaks orthogonality, isn't logically necessary, and was probably put there for the convenience of implementors, which is usually a bad decision. But that's the way the spec is, and we have to live with it.)
>

Yes you probably read my mind. It is a rule that catches me out
repeatedly and  a bit of a double whammy in that the remedy entails
something else I find somewhat mysterious anyway - document nodes.

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: A bug methinks. To barf or not to barf. That is the question.

Ihe Onwuka-2
In reply to this post by Michael Kay
On Mon, Mar 24, 2014 at 10:17 AM, Michael Kay <[hidden email]> wrote:

>>
>> I'm now going to explore why it doesn't fail in the absence of the parent::*.
>>
>
> Adding an xsl:message shows that in the absence of the parent::*, the $amounts variable is like this (I've removed unnecessary namespaces and added indentation)
>
> <amounts>
>   <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
>   <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
> </amounts>
>
> This doesn't cause recursive invocation of the EffectiveDate template because you have a higher-priority rule matching amounts/EffectiveDate.
>
> With parent::* added back in, the variable is now:
>
> <amounts>
>   <BaseRentEntry>
>     <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
>     <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
>   </BaseRentEntry>
>   <EffectiveDate RelativeTo="Absolute">1995-09-01</EffectiveDate>
>   <RentAmount UnitOfMeasure="AnnualAmount">8813.2</RentAmount>
> </amounts>
>
> And the first EffectiveDate element causes the recursive invocation, because it doesn't match amounts/EffectiveDate.
>
> So, no bug: Saxon is getting it right in both cases.
>

Right  so false alarm.

Well I blame Martin Holmes. He's the one that showed me the technique
of constructing variables so that you can apply templates to them. :)

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help