def Map(context, nodeset, string): if type(nodeset) != type([]): raise RuntimeException(RuntimeException.WRONG_ARGUMENTS, 'map', "expected node set argument") from Ft.Xml.XPath import parser from Ft.Lib import Set from rx import raccoon mapContext = context.clone() mapContext.size = len(nodeset) mapContext.position = 1 #note: exslt-dyn:map implies that parse exception should be caught and an empty nodeset returned expCache = raccoon.RequestProcessor.expCache xpath = StringValue(string) queryCache = getattr(context.node.ownerDocument, 'queryCache', None) def eval(l, node): mapContext.node = node mapContext.position += 1 mapContext.varBindings[(RXWIKI_XPATH_EXT_NS, 'current')] = node result = RxPath.evalXPath(xpath, mapContext, expCache, queryCache) if type(result) != type([]): if not isinstance(result, unicode): result = unicode(str(result), 'utf8') result = String2NodeSet(mapContext, result) l.extend(result) return l nodeset = reduce(eval, nodeset, []) return Set.Unique(nodeset)
def _ParsedAbbreviatedRelativeLocationPath_evaluate(self, context): if getattr(context.node, 'getSafeChildNodes', None): step = findNextStep(self._right) if isChildAxisSpecifier(step): #change next step from child to descendant #todo: bug if you reuse this parsed expression on a non-RxPath dom step._axis = XPath.ParsedAxisSpecifier.ParsedAxisSpecifier( 'descendant') if hasattr(self, '_middle'): #for older 4Suite versions #make _middle does no filtering self._middle._axis = XPath.ParsedAxisSpecifier.ParsedAxisSpecifier( 'self') nodeset = self._left.select(context) state = context.copy() size = len(nodeset) result = [] for pos in range(size): context.node, context.position, context.size = \ nodeset[pos], pos + 1, size subRt = self._right.select(context) result = Set.Union(result, subRt) context.set(state) return result return _ParsedAbbreviatedRelativeLocationPath_oldEvaluate( self, context)
def Id(context, object): """Function: <node-set> id(<object>)""" id_list = [] if type(object) != type([]): st = StringValue(object) id_list = st.split() else: for n in object: id_list.append(StringValue(n)) doc = context.node.rootNode getElementById = getattr(doc, 'getElementById', None) if not getElementById: #this is from 4suite 1.0a3's version of id(): import warnings warnings.warn("id() function not supported") #We do not (cannot, really) support the id() function return [] nodeset = [] for id in id_list: element = getElementById(id) if element: nodeset.append(element) return Set.Unique(nodeset)
def updateKey(self, doc, keyName, processor): """ Update a particular key for a new document """ from pprint import pprint if doc not in processor.keys: processor.keys[doc] = {} if keyName not in processor.keys[doc]: key_values = processor.keys[doc][keyName] = {} else: key_values = processor.keys[doc][keyName] try: keys = self._keys[keyName] except KeyError: return # Find the matching nodes using all matching xsl:key elements updates = {} for key in keys: match_pattern, use_expr, namespaces = key context = XsltContext.XsltContext( doc, 1, 1, processorNss=namespaces, processor=processor, extFunctionMap=self.initialFunctions) patterns = PatternList([match_pattern], namespaces) matched = MatchTree(patterns, context)[0] for node in matched: state = context.copy() context.node = node key_value_list = use_expr.evaluate(context) if not isinstance(key_value_list, list): key_value_list = [key_value_list] for key_value in key_value_list: key_value = Conversions.StringValue(key_value) if key_value not in updates: updates[key_value] = [node] else: updates[key_value].append(node) context.set(state) # Put the updated results in document order with duplicates removed for key_value in updates: if key_value in key_values: nodes = Set.Union(key_values[key_value], updates[key_value]) else: nodes = Set.Unique(updates[key_value]) key_values[key_value] = nodes return
def test_not(tester): tester.startTest("Not") a = [1,2,3] b = [2,3,4] res = Set.Not(a,b) tester.compare(1,len(res)) tester.compareIn(res,1) tester.testDone()
def test_unique(tester): tester.startTest("Unique") a = [1,2,3,2] res = Set.Unique(a) tester.compare(3,len(res)) tester.compareIn(res,1) tester.compareIn(res,2) tester.compareIn(res,3) tester.testDone()
def test_intersection(tester): tester.startTest("Intersection") a = [1,2,3] b = [2,3,4] res = Set.Intersection(a,b) tester.compare(2,len(res)) tester.compareIn(res,2) tester.compareIn(res,3) tester.testDone()
def _FunctionCallEvaluate(self, context, oldFunc): #make XPath.ParsedExpr.FunctionCall*.evaluate have no side effects so we can cache them if self._name != 'evalRxPathQuery': self._func = None retVal = oldFunc(self, context) #prevent expressions that are just function calls #from returning nodesets with duplicate nodes if type(retVal) == type([]): return Set.Unique(retVal) else: return retVal
def test_union(tester): tester.startTest("Union") a = [1,2,3] b = [2,3,4] res = Set.Union(a,b) tester.compare(4,len(res)) tester.compareIn(res,1) tester.compareIn(res,2) tester.compareIn(res,3) tester.compareIn(res,4) tester.testDone()
def Id(context, object_): """Function: <node-set> id(<object>)""" if not isinstance(object_, NodesetType): st = Conversions.StringValue(object_) id_list = st.split() else: id_list = [Conversions.StringValue(n) for n in object_] id_list = Set.Unique(id_list) doc = context.node.rootNode nodeset = [] for id in id_list: element = doc.getElementById(id) if element: nodeset.append(element) return nodeset
def _descendants(self, context, nodeset, nextStepAttr, startNode=None): startNode = startNode or context.node childNodeFunc = getattr(context.node, 'getSafeChildNodes', None) if childNodeFunc: childNodes = childNodeFunc(startNode) else: childNodes = context.node.childNodes nextStep = getattr(self, nextStepAttr) nodeTest = None if childNodeFunc: step = findNextStep(nextStep) nodeTest = getattr(step, '_nodeTest', None) for child in childNodes: context.node = child #if an RxPath DOM then only evaluate predicate nodes if childNodeFunc: if isPredicate(context, [child]): if nodeTest: #no nodeTest is equivalent to node() if not nodeTest.match(context, context.node, step._axis.principalType): continue #we're a RxPath dom and the nodetest didn't match, don't examine the node's descendants results = nextStep.select(context) else: results = [] else: results = nextStep.select(context) # Ensure no duplicates if results: if preNodeSorting4Suite: #need to do inplace filtering nodeset.extend( filter(lambda n, s=nodeset: n not in s, results)) else: nodeset.extend(results) nodeset = Set.Unique(nodeset) if child.nodeType == Node.ELEMENT_NODE: nodeset = self._descendants(context, nodeset, startNode) return nodeset
def MapImpl(context, nodeset, expr): ctx = context.clone() try: result = [] size = len(nodeset) inputs = enumerate(nodeset) try: index, n = inputs.next() ctx.node = n ctx.size = size ctx.pos = index + 1 try: partial = expr.evaluate(ctx) except RuntimeException: tb = handle_traceback() msg = 'Exception evaluating XPath "%s", masked by empty node set partial result:\n%s' % ( expr, tb.getvalue()) context.processor.warning(msg) partial = [] for ntype in NODE_HANDLERS: if isinstance(partial, ntype): node_handler = NODE_HANDLERS[ntype] break else: #FIXME L10N raise TypeError('Unknown node type') node_element, converter = node_handler if node_element: e = context.node.rootNode.createElementNS( EXSL_COMMON_NS, node_element) t = context.node.rootNode.createTextNode(converter(partial)) e.appendChild(t) result.append(e) else: result = Set.Union(result, partial) except StopIteration: pass for index, n in inputs: ctx.node = n ctx.size = size ctx.pos = index + 1 try: partial = expr.evaluate(ctx) except RuntimeException: tb = handle_traceback() msg = 'Syntax error in XPath "%s", masked by empty node set return:\n%s' % ( string, tb.getvalue()) context.processor.warning(msg) partial = [] if node_element: e = context.node.rootNode.createElementNS( EXSL_COMMON_NS, node_element) t = context.node.rootNode.createTextNode(converter(partial)) e.appendChild(t) result.append(e) else: result = Set.Union(result, partial) except: import traceback traceback.print_exc() result = [] return result