[4suite] Ft.Xml.Xslt templates matching attributes with predicates

Krzysztof Nosek krzysztof.nosek at techland.pl
Wed Jul 11 05:17:53 MDT 2007


Hello guys,

Due to lack of interest on the list I tried to inspect this problem by myself.
(see http://lists.fourthought.com/pipermail/4suite/2007-April/008243.html for
reference)

According to my opinion our trouble begins (or rather, we're already deep in them)
at StylesheetElement.applyTemplates() (Stylesheet.py, line 527):

http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/Stylesheet.py?view=markup

The table with patterns for elements is a dict hashed by name, cool. However, the
table with patterns for attributes is a straight list. So even if we are in
context of attribute @a, we are matching template patterns for both @* and @error
(and generally all attribute patterns, if there are more).

So far, so good, if it is simple name pattern as in
<xsl:template match="@error">
which fires LocalNameTest.match(), or if it is wildcard pattern as in
<xsl:template match="@*">
which fires PrincipialTypeTest.match(). But if the pattern contains a predicate:

<xsl:template match="@error[ true() ]">

we use PredicatedNodeTest.match(). See XPatterns.py
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/XPatterns.py?view=markup
and its line 125:

        if principalType == Node.ATTRIBUTE_NODE:
            node_set = node.ownerElement.attributes.values()

So in context of attribute @a, when matching predicate pattern for @error, we take
for working node_set... all sibling attributes, namely @a, @b and @error.

Of course attribute @error passes both nodeTest and all predicates, and is
therefore returned as a result of the "succesful" match. We instantiate the
template and break the pattern-matching loop.

This is incorrect.

Here is my ad hoc patch for the problem:
==============================================================
--- XPatterns.py.bak	Wed Jul 11 12:11:30 2007
+++ XPatterns.py	Wed Jul 11 13:07:35 2007
@@ -122,7 +122,7 @@

     def match(self, context, node, principalType):
         if principalType == Node.ATTRIBUTE_NODE:
-            node_set = node.ownerElement.attributes.values()
+            node_set = [node]
         elif node.parentNode:
             node_set = node.parentNode.childNodes
         else:
==============================================================
However, I don't really follow what the line 125 serves for, so it may be a very
bad hack.

I am looking forward for your reviews and a new 4Suite release with the bug fixed :)

Regards,
Krzysztof Nosek




More information about the 4suite mailing list