예제 #1
0
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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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
예제 #5
0
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()    
예제 #6
0
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()    
예제 #7
0
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()    
예제 #8
0
        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
예제 #9
0
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()    
예제 #10
0
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
예제 #11
0
    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
예제 #12
0
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