After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 307103 - Templates dont match
Templates dont match
Status: RESOLVED FIXED
Product: libxslt
Classification: Platform
Component: general
1.1.14
Other Linux
: Normal normal
: ---
Assigned To: kbuchcik
libxml QA maintainers
Depends on:
Blocks:
 
 
Reported: 2005-06-10 06:49 UTC by Gero Meißner
Modified: 2006-07-14 16:21 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Gero Meißner 2005-06-10 06:49:00 UTC
Using libxml 20619, libxslt 10114 and libexslt 812
xsltproc was compiled against libxml 20619, libxslt 10114 and libexslt 812
libxslt 10114 was compiled against libxml 20619
libexslt 812 was compiled against libxml 20619

THE DOCUMENT:
-------------
<?xml version="1.0" encoding="UTF-8"?>
<firmenindex>
<hvfi:firma 
xmlns:hvfi="http://www.heinze.de/xmlns/herstellerverzeichnis/firmen">
<hvfi:adresse>
<name>Mustermann#1</name>
<name>Mustermann#2</name>
<name>Mustermann#3</name>
</hvfi:adresse>
</hvfi:firma>
</firmenindex>

THE STYLESHEET:
---------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:hzfo="http://www.heinze.de/xmlns/formating-objects/"
                exclude-result-prefixes="hzfo">

<xsl:import href="./module1.xsl"/>
<xsl:import href="./module2.xsl"/>
<xsl:import href="./module3.xsl"/>
<xsl:import href="./module4.xsl"/>

<xsl:output method="xml"/>

<xsl:template match="/">
  <xsl:apply-templates select="." mode="hzfo:page.sequence"/>
</xsl:template>

</xsl:stylesheet>

THE MODULE #1:
--------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:hzfo="http://www.heinze.de/xmlns/formating-objects/"
                
xmlns:hvfi="http://www.heinze.de/xmlns/herstellerverzeichnis/firmen"
                exclude-result-prefixes="hzfo">

<xsl:template match="firmenindex"
              mode="hzfo:page.sequence">
  <xsl:text> template#1 in module#1</xsl:text>
  <xsl:apply-templates select="hvfi:firma"/>
</xsl:template>

</xsl:stylesheet>

THE MODULE #2:
--------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:hzfo="http://www.heinze.de/xmlns/formating-objects/"
                
xmlns:hvfi="http://www.heinze.de/xmlns/herstellerverzeichnis/firmen"
                exclude-result-prefixes="hzfo">

<xsl:template match="hvfi:firma"
              mode="hzfo:header">
  <xsl:text> template#1 in module#2</xsl:text>
  <xsl:apply-templates select="hvfi:adresse"/>
</xsl:template>


<xsl:template match="hvfi:firma"
              mode="hzfo:header.first">
  <xsl:text> template#2 in module#2</xsl:text>
  <xsl:apply-templates select="hvfi:adresse"/>
</xsl:template>

</xsl:stylesheet>

THE MODULE #3:
--------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                
xmlns:hvfi="http://www.heinze.de/xmlns/herstellerverzeichnis/firmen">

<xsl:template match="hvfi:adresse/name[position()=1]">
  <xsl:text> template#1 in module#3</xsl:text>
  <xsl:value-of select="."/>
</xsl:template>


<xsl:template match="hvfi:adresse/name[position()=2]">
  <xsl:text> template#2 in module#3</xsl:text>
  <xsl:value-of select="."/>
</xsl:template>


<xsl:template match="hvfi:adresse/name[position()>2]">
  <xsl:text> template#3 in module#3</xsl:text>
  <xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

THE MODULE #4:
--------------
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:hzfo="http://www.heinze.de/xmlns/formating-objects/"
                
xmlns:hvfi="http://www.heinze.de/xmlns/herstellerverzeichnis/firmen"
                exclude-result-prefixes="hzfo">

<xsl:template match="hvfi:firma">
  <xsl:apply-templates select="." mode="hzfo:header"/>
  <xsl:apply-templates select="." mode="hzfo:header.first"/>
</xsl:template>


<xsl:template match="hvfi:adresse">
  <xsl:apply-templates select="name[position()=1]"/>
  <xsl:apply-templates select="name[position()=2]"/>
</xsl:template>

</xsl:stylesheet>

THE RESULT WITH LibXSLT:
------------------------
<?xml version="1.0"?>
 template#1 in module#1 template#1 in module#2 template#1 in 
module#3Mustermann#1 template#2 in module#3Mustermann#2 template#2 in module#2 
template#1 in module#3Mustermann#1Mustermann#2

THE RESULT WITH MSXML, Saxon, Sablotron:
----------------------------------------
<?xml version="1.0" encoding="UTF-8"?> template#1 in module#1 template#1 in 
module#2 template#1 in module#3Mustermann#1 template#2 in module#3Mustermann#2 
template#2 in module#2 template#1 in module#3Mustermann#1 template#2 in 
module#3Mustermann#2


Regards
Gero
Comment 1 kbuchcik 2006-04-11 15:26:38 UTC
Reduced, human-readable results:
Libxslt
"...
Mustermann#1
Mustermann#2"

Other
"...
Mustermann#1
template#2 in module#3
Mustermann#2"

So it seems Libxslt is missing a call to the following template in "module3.xsl":

<xsl:template match="hvfi:adresse/name[position()=2]">
  <xsl:text> template#2 in module#3</xsl:text>
  <xsl:value-of select="."/>
</xsl:template>
Comment 2 kbuchcik 2006-07-13 15:34:51 UTC
In xsltTestCompMatch() the proximity position incorrectly evaluates
to 1 (shold be 2) the second time the template match of
<xsl:template match="hvfi:adresse/name[position()=2]">
is evaluated, thus the "position()=2" predicate evaluates
to false.
This is strange, since this template is invoked by the following
template both times:

<xsl:template match="hvfi:adresse">
  <xsl:apply-templates select="name[position()=1]"/>
  <xsl:apply-templates select="name[position()=2]"/>
</xsl:template>

The first processing of
<xsl:apply-templates select="name[position()=2]"/>
finds the template, the *second* not.

More details:
In In xsltTestCompMatch() we have:
ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);

The first time the template match is evaluated, @ix evaluates to 1;
the second time the same template is evaluated, @ix results in 0 for
the same context node.
Some later code then computes the proximity position:
pos = ix + indx;
Which correctly is 2 the first time, and incorrectly 1 the second time.

Does the
ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);
maybe use some stored values on the compiled expression, so that
evaluating it a second time, wrong values are used?
Is a cleanup of the compiled expression, after evaluating it,
maybe missed somewhere?



Comment 3 kbuchcik 2006-07-14 09:50:08 UTC
Here is the sequence of events which lead to the bug:

1) Processing <xsl:apply-templates select="name[position()=2]"/>
  --> the 2nd "name" element becomes the context node
  --> Processing <xsl:template match="hvfi:adresse/name[position()=2]">
    Some values are stored:
      ctxt->extras[(sel->indexExtra)].val.ival = 2
      ctxt->extras[(sel->indexExtra)].val.ival = 2nd "name" element

The second time this sequence of templates is invoked:  
2) Processing <xsl:apply-templates select="name[position()=2]"/>
  --> the 1st "name" element becomes the context node
  --> Processing <xsl:template match="hvfi:adresse/name[position()=2]">
      The stored values are retrieved:
      @ix == 2
      @previous == 2nd "name" element

At this point @previous is now a *following-sibling* - not a
preceding-sibling - of the context node; this means that the
computation of the proximity position relative to @previous
fails and a fallback-computation for such a reverse case is
performed.

And now comes the bug: the fallback-computation misses to
skip text nodes and the position is computed incorrectly.
Adjusting this fallback code to work exactly as in the 
normal code heals the problem.

I'll try to commit the fix today.
Comment 4 kbuchcik 2006-07-14 09:53:00 UTC
Correction, in point 2) it should read (note the "position()=1"):

2) Processing <xsl:apply-templates select="name[position()=1]"/>
Comment 5 kbuchcik 2006-07-14 16:21:58 UTC
Fixed in CVS.