[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