[4suite-checkins] [XPATH_OPTIMIZATIONS-branch] In
4Suite/Ft/Xml/Xslt, files ApplyTemplatesElement.py,
AttributeValueTemplate.py, ChooseElement.py, ForEachElement.py,
IfElement.py, NumberElement.py, ValueOfElement.py,
XPathExtensions.py, XsltFunctions.py
Jeremy Kloth
jkloth at 4suite.org
Mon Dec 4 00:56:51 MST 2006
Branch: XPATH_OPTIMIZATIONS-branch
Modified Files:
ApplyTemplatesElement.py AttributeValueTemplate.py ChooseElement.py
ForEachElement.py IfElement.py NumberElement.py ValueOfElement.py
XPathExtensions.py XsltFunctions.py
Log Message:
Preliminary optimizations for XPath. It may or may not work on others'
machines, but it is time that these optimizations see the light of day.
This will be the only way to ensure they work 100% and can be incorporated
into the trunk.
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ApplyTemplatesElement.py.diff?r1=1.11&r2=1.11.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ApplyTemplatesElement.py?rev=1.11.2.1&content-type=text/vnd.viewcvs-markup
Index: ApplyTemplatesElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/ApplyTemplatesElement.py,v
retrieving revision 1.11
retrieving revision 1.11.2.1
diff -U2 -r1.11 -r1.11.2.1
--- ApplyTemplatesElement.py 27 Nov 2006 16:29:29 -0000 1.11
+++ ApplyTemplatesElement.py 4 Dec 2006 07:56:51 -0000 1.11.2.1
@@ -59,9 +59,9 @@
if self._select:
- node_set = self._select.evaluate(context)
- # it must really be a node-set, and if XSLT 1.0, not a result tree fragment
- if not isinstance(node_set, list):
- raise XsltRuntimeException(
- Error.ILLEGAL_APPLYTEMPLATE_NODESET, self)
+ try:
+ node_set = self._select.evaluateAsNodeSet(context)
+ except TypeError:
+ raise XsltRuntimeException(Error.ILLEGAL_APPLYTEMPLATE_NODESET,
+ self)
else:
node_set = context.node.childNodes
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/AttributeValueTemplate.py.diff?r1=1.11&r2=1.11.4.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/AttributeValueTemplate.py?rev=1.11.4.1&content-type=text/vnd.viewcvs-markup
Index: AttributeValueTemplate.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/AttributeValueTemplate.py,v
retrieving revision 1.11
retrieving revision 1.11.4.1
diff -U2 -r1.11 -r1.11.4.1
--- AttributeValueTemplate.py 17 Aug 2006 14:53:54 -0000 1.11
+++ AttributeValueTemplate.py 4 Dec 2006 07:56:51 -0000 1.11.4.1
@@ -48,6 +48,5 @@
self.element = context.currentInstruction
- convert = Conversions.StringValue
- result = self._resultFormat % tuple([ convert(x.evaluate(context))
+ result = self._resultFormat % tuple([ x.evaluateAsString(context)
for x in self._parsedParts ])
if self.validator:
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ChooseElement.py.diff?r1=1.6&r2=1.6.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ChooseElement.py?rev=1.6.2.1&content-type=text/vnd.viewcvs-markup
Index: ChooseElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/ChooseElement.py,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -U2 -r1.6 -r1.6.2.1
--- ChooseElement.py 29 Nov 2006 02:10:08 -0000 1.6
+++ ChooseElement.py 4 Dec 2006 07:56:51 -0000 1.6.2.1
@@ -52,5 +52,5 @@
self._choices = self.children
self._otherwise = None
- self._choices = [ (child, child._test.evaluate)
+ self._choices = [ (child, child._test.evaluateAsBoolean)
for child in self._choices ]
return
@@ -61,5 +61,5 @@
context.processorNss = child.namespaces
context.currentInstruction = child
- if Conversions.BooleanValue(test(context)):
+ if test(context):
chosen = child
break
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ForEachElement.py.diff?r1=1.8&r2=1.8.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ForEachElement.py?rev=1.8.2.1&content-type=text/vnd.viewcvs-markup
Index: ForEachElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/ForEachElement.py,v
retrieving revision 1.8
retrieving revision 1.8.2.1
diff -U2 -r1.8 -r1.8.2.1
--- ForEachElement.py 27 Nov 2006 16:29:29 -0000 1.8
+++ ForEachElement.py 4 Dec 2006 07:56:51 -0000 1.8.2.1
@@ -42,14 +42,15 @@
if self._select:
- node_set = self._select.evaluate(context)
- if type(node_set) != type([]):
+ try:
+ node_set = self._select.select(context, [context.node])
+ except TypeError:
raise XsltRuntimeException(Error.INVALID_FOREACH_SELECT, self)
else:
- node_set = context.node.childNodes
+ node_set = context.node
children = [ child.instantiate for child in self.children ]
state = context.node, context.position, context.size
pos = 1
- size = len(node_set)
+ size = 0 #len(node_set)
for node in node_set:
context.node, context.position, context.size = node, pos, size
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/IfElement.py.diff?r1=1.5&r2=1.5.6.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/IfElement.py?rev=1.5.6.1&content-type=text/vnd.viewcvs-markup
Index: IfElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/IfElement.py,v
retrieving revision 1.5
retrieving revision 1.5.6.1
diff -U2 -r1.5 -r1.5.6.1
--- IfElement.py 6 Apr 2005 23:05:47 -0000 1.5
+++ IfElement.py 4 Dec 2006 07:56:51 -0000 1.5.6.1
@@ -29,5 +29,5 @@
context.currentInstruction = self
- if Conversions.BooleanValue(self._test.evaluate(context)):
+ if self._test.evaluateAsBoolean(context):
for child in self.children:
child.instantiate(context, processor)
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/NumberElement.py.diff?r1=1.10&r2=1.10.6.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/NumberElement.py?rev=1.10.6.1&content-type=text/vnd.viewcvs-markup
Index: NumberElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/NumberElement.py,v
retrieving revision 1.10
retrieving revision 1.10.6.1
diff -U2 -r1.10 -r1.10.6.1
--- NumberElement.py 6 Apr 2005 23:05:47 -0000 1.10
+++ NumberElement.py 4 Dec 2006 07:56:51 -0000 1.10.6.1
@@ -104,5 +104,5 @@
# get value(s) to format
if self._value:
- value = Conversions.NumberValue(self._value.evaluate(context))
+ value = self._value.evaluateAsNumber(context)
if not number.finite(value) or value < 0.5:
# This is an error. However, recovery is to just write
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ValueOfElement.py.diff?r1=1.9&r2=1.9.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/ValueOfElement.py?rev=1.9.2.1&content-type=text/vnd.viewcvs-markup
Index: ValueOfElement.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/ValueOfElement.py,v
retrieving revision 1.9
retrieving revision 1.9.2.1
diff -U2 -r1.9 -r1.9.2.1
--- ValueOfElement.py 27 Nov 2006 16:29:29 -0000 1.9
+++ ValueOfElement.py 4 Dec 2006 07:56:51 -0000 1.9.2.1
@@ -25,5 +25,5 @@
context.currentInstruction = self
- text = Conversions.StringValue(self._select.evaluate(context))
+ text = self._select.evaluateAsString(context)
if text:
if self._disable_output_escaping:
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/XPathExtensions.py.diff?r1=1.10&r2=1.10.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/XPathExtensions.py?rev=1.10.2.1&content-type=text/vnd.viewcvs-markup
Index: XPathExtensions.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/XPathExtensions.py,v
retrieving revision 1.10
retrieving revision 1.10.2.1
diff -U2 -r1.10 -r1.10.2.1
--- XPathExtensions.py 27 Nov 2006 16:29:29 -0000 1.10
+++ XPathExtensions.py 4 Dec 2006 07:56:51 -0000 1.10.2.1
@@ -1,7 +1,10 @@
-class RtfExpr:
+from Ft.Xml.XPath.ParsedExpr import Expression
+
+class RtfExpr(Expression):
+
def __init__(self, nodes):
self.nodes = nodes
- def evaluate(self, context):
+ def evaluateAsNodeSet(self, context):
processor = context.processor
processor.pushResultTree(context.currentInstruction.baseUri)
@@ -17,4 +20,5 @@
pass
return result
+ evaluate = evaluateAsNodeSet
def pprint(self, indent=''):
@@ -23,7 +27,8 @@
def __str__(self):
return '<RtfExpr at %x: %s>' % (id(self), str(self.nodes))
-
-class SortedExpression:
+
+class SortedExpression(Expression):
+
def __init__(self, expression, sortKeys):
self.expression = expression
@@ -43,11 +48,9 @@
return cmp(node1, node2)
- def evaluate(self, context):
+ def evaluateAsNodeSet(self, context):
if self.expression is None:
base = context.node.childNodes
else:
- base = self.expression.evaluate(context)
- if type(base) is not type([]):
- raise TypeError('expected nodeset, %s found' % type(base).__name__)
+ base = self.expression.evaluateAsNodeSet(context)
# create initial sort structure
@@ -69,2 +72,3 @@
# extract the sorted nodes
return map(lambda nk: nk[0], nodekeys)
+ evaluate = evaluateAsNodeSet
ViewCVS diff:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/XsltFunctions.py.diff?r1=1.47&r2=1.47.2.1
ViewCVS view:
http://cvs.4suite.org/viewcvs/4Suite/Ft/Xml/Xslt/XsltFunctions.py?rev=1.47.2.1&content-type=text/vnd.viewcvs-markup
Index: XsltFunctions.py
===================================================================
RCS file: /var/local/cvsroot/4Suite/Ft/Xml/Xslt/XsltFunctions.py,v
retrieving revision 1.47
retrieving revision 1.47.2.1
diff -U2 -r1.47 -r1.47.2.1
--- XsltFunctions.py 27 Nov 2006 16:29:29 -0000 1.47
+++ XsltFunctions.py 4 Dec 2006 07:56:51 -0000 1.47.2.1
@@ -14,6 +14,6 @@
from Ft.Xml import __version__, EMPTY_NAMESPACE
from Ft.Xml.Lib import routines
-from Ft.Xml.XPath import Conversions, FT_EXT_NAMESPACE
-from Ft.Xml.XPath.XPathTypes import NodesetType
+from Ft.Xml.XPath import FT_EXT_NAMESPACE
+from Ft.Xml.XPath.cDataTypes import *
from Ft.Xml.Xslt import XsltRuntimeException, Error, XSL_NAMESPACE
from Ft.Xml.Xslt.StylesheetHandler import ELEMENT_MAPPING
@@ -83,5 +83,5 @@
if nodeSet:
- if not isinstance(nodeSet, NodesetType):
+ if not isinstance(nodeSet, NodeSet):
raise XsltRuntimeException(Error.WRONG_ARGUMENT_TYPE,
context.currentInstruction)
@@ -100,6 +100,6 @@
# arg1 is not a node-set
- if not isinstance(object, NodesetType):
- ref = Conversions.StringValue(object)
+ if not isinstance(object, NodeSet):
+ ref = String(object)
# check base URI coming from arg 2 only when it's needed
if IsAbsolute(ref):
@@ -119,5 +119,5 @@
else:
for node in object:
- ref = Conversions.StringValue(node)
+ ref = String(node)
if IsAbsolute(ref):
base=ref
@@ -182,9 +182,9 @@
context node that have a value for the named key equal to this string.
"""
- qname = Conversions.StringValue(qname)
+ qname = String(qname)
if not qname:
raise XsltRuntimeException(Error.INVALID_QNAME_ARGUMENT,
context.currentInstruction, qname)
- split_name = context.expandQName(Conversions.StringValue(qname))
+ split_name = context.expandQName(String(qname))
doc = context.node.rootNode
try:
@@ -198,10 +198,10 @@
result = []
- if not isinstance(keyList, NodesetType):
+ if not isinstance(keyList, NodeSet):
keyList = [keyList]
for key in keyList:
- key = Conversions.StringValue(key)
+ key = String(key)
result.extend(requested_key.get(key, []))
- return result
+ return NodeSet(result)
@@ -212,5 +212,5 @@
Returns a node-set that has the current node as its only member.
"""
- return [context.currentNode]
+ return NodeSet([context.currentNode])
@@ -223,7 +223,7 @@
if there is no such entity.
"""
- name = Conversions.StringValue(name)
+ name = String(name)
unparsedEntities = getattr(context.node.rootNode, 'unparsedEntities', {})
- return unparsedEntities.get(name, u'')
+ return String(unparsedEntities.get(name, u''))
@@ -242,12 +242,12 @@
if nodeSet is None:
# If no argument is given, use the context node
- return u'id%r' % id(context.node)
+ return String('id%r' % id(context.node))
elif nodeSet:
# first node in nodeset in document order
nodeSet.sort()
- return u'id%r' % id(nodeSet[0])
+ return String('id%r' % id(nodeSet[0]))
else:
# When the nodeset is empty, return an empty string
- return u''
+ return String.EMPTY
@@ -266,5 +266,5 @@
and platform in the %s namespace.
""" % FT_EXT_NAMESPACE
- qname = Conversions.StringValue(qname)
+ qname = String(qname)
#FIXME: actual test should ensure split_name is a QName
if not qname:
@@ -274,21 +274,21 @@
if uri == XSL_NAMESPACE:
if local == 'version':
- return 1.0
+ return Number(1.0)
if local == 'vendor':
- return u"Fourthought Inc."
+ return String("Fourthought Inc.")
if local == 'vendor-url':
- return u"http://4Suite.org"
+ return String("http://4Suite.org")
elif uri == 'http://xmlns.4suite.org/xslt/env-system-property':
- return unicode(os.environ.get(local, ''))
+ return String(os.environ.get(local, ''))
elif uri == FT_EXT_NAMESPACE:
if local == 'version':
- return __version__
+ return String(__version__)
if local == 'tempdir':
#Returns the directory used by the OS for temporary files
import tempfile
- return unicode(tempfile.gettempdir())
+ return String(tempfile.gettempdir())
if local == 'platform':
- return unicode(sys.platform)
- return u''
+ return String(sys.platform)
+ return String.EMPTY
@@ -303,13 +303,13 @@
defined by XPath or XSLT.
"""
- qname = Conversions.StringValue(qname)
+ qname = String(qname)
#FIXME: actual test should ensure split_name is a QName
if not qname:
- return boolean.false
+ return Boolean.FALSE
split_name = context.expandQName(qname)
if split_name in context.functions:
- return boolean.true
+ return Boolean.TRUE
else:
- return boolean.false
+ return Boolean.FALSE
@@ -325,8 +325,8 @@
element-available function will return false.
"""
- qname = Conversions.StringValue(qname)
+ qname = String(qname)
#FIXME: actual test should ensure split_name is a QName
if not qname:
- return boolean.false
+ return Boolean.FALSE
namespaceURI, localName = expandedName = context.expandQName(qname)
@@ -338,5 +338,5 @@
available = False
- return available and boolean.true or boolean.false
+ return available and Boolean.TRUE or Boolean.FALSE
@@ -355,7 +355,7 @@
decimal-format with the specified expanded-name.
"""
- num = Conversions.NumberValue(number)
+ num = Number(number)
- format_string = Conversions.StringValue(formatString)
+ format_string = String(formatString)
if decimalFormatName is not None:
@@ -369,5 +369,5 @@
decimalFormatName)
- return routines.FormatNumber(num, format_string, decimal_format)
+ return String(routines.FormatNumber(num, format_string, decimal_format))
More information about the 4suite-checkins
mailing list