示例#1
0
def SubstringBefore(context, outer, inner):
    """Function: <string> substring-before(<string>, <string>)"""
    outer = Conversions.StringValue(outer)
    inner = Conversions.StringValue(inner)
    index = string.find(outer, inner)
    if index == -1:
        return ''
    return outer[:index]
示例#2
0
def SubstringAfter(context, outer, inner):
    """Function: <string> substring-after(<string>, <string>)"""
    outer = Conversions.StringValue(outer)
    inner = Conversions.StringValue(inner)
    index = string.find(outer, inner)
    if index == -1:
        return ''
    return outer[index + len(inner):]
示例#3
0
def Replace(context, old, new, arg=None):
    """Do a global search and replace of the string contents"""
    if not arg:
        arg = context.node
    arg = Conversions.StringValue(arg)
    old = Conversions.StringValue(old)
    new = Conversions.StringValue(new)
    return string.replace(arg, old, new)
示例#4
0
def Contains(context, outer, inner):
    """Function: <string> contains(<string>, <string>)"""
    outer = Conversions.StringValue(outer)
    inner = Conversions.StringValue(inner)
    if len(inner) == 1:
        return inner in outer and boolean.true or boolean.false
    else:
        return string.find(outer,
                           inner) != -1 and boolean.true or boolean.false
示例#5
0
def range(context, lo, hi):
    doc = context.node
    while doc.parentNode:
        doc = doc.parentNode

    lo = Conversions.NumberValue(lo)
    hi = Conversions.NumberValue(hi)

    nodeset = []
    for number in xrange(lo, hi):
        nodeset.append(doc.createTextNode(str(number)))

    return nodeset
示例#6
0
 def evaluate(self, context):
     '''returns a number'''
     if self._leftLit:
         lrt = self._left
     else:
         lrt = self._left.evaluate(context)
         lrt = Conversions.NumberValue(lrt)
     if self._rightLit:
         rrt = self._right
     else:
         rrt = self._right.evaluate(context)
         rrt = Conversions.NumberValue(rrt)
     return lrt + (rrt * self._sign)
示例#7
0
    def evaluate(self, context):
        if self._op == '=':
            true = boolean.true
            false = boolean.false
        else:
            true = boolean.false
            false = boolean.true

        lrt = self._left.evaluate(context)
        rrt = self._right.evaluate(context)
        lType = type(lrt)
        rType = type(rrt)
        if lType == types.ListType == rType:
            #Node set to node set
            for right_curr in rrt:
                right_curr = Conversions.StringValue(right_curr)
                for left_curr in lrt:
                    if right_curr == Conversions.StringValue(left_curr):
                        return true
            return false
        elif lType == types.ListType or rType == types.ListType:
            func = None
            if lType == types.ListType:
                set = lrt
                val = rrt
            else:
                set = rrt
                val = lrt
            if type(val) in NumberTypes:
                func = Conversions.NumberValue
            elif boolean.IsBooleanType(val):
                func = Conversions.BooleanValue
            elif type(val) == types.StringType:
                func = Conversions.StringValue
            else:
                #Deal with e.g. RTFs
                val = Conversions.StringValue(val)
                func = Conversions.StringValue
            for n in set:
                if func(n) == val:
                    return true
            return false

        if boolean.IsBooleanType(lrt) or boolean.IsBooleanType(rrt):
            rt = Conversions.BooleanValue(lrt) == Conversions.BooleanValue(rrt)
        elif lType in NumberTypes or rType in NumberTypes:
            rt = Conversions.NumberValue(lrt) == Conversions.NumberValue(rrt)
        else:
            rt = Conversions.StringValue(lrt) == Conversions.StringValue(rrt)
        if rt:
            # Due to the swapping of true/false, true might evaluate to 0
            # We cannot compact this to 'rt and true or false'
            return true
        return false
示例#8
0
 def __init__(self, sign, left, right):
     self._sign = sign
     self._leftLit = 0
     self._rightLit = 0
     if isinstance(left, ParsedLiteralExpr):
         self._leftLit = 1
         self._left = Conversions.NumberValue(left.evaluate(None))
     else:
         self._left = left
     if isinstance(right, ParsedLiteralExpr):
         self._rightLit = 1
         self._right = Conversions.NumberValue(right.evaluate(None))
     else:
         self._right = right
     return
示例#9
0
def Translate(context, source, fromChars, toChars):
    """Function: <string> translate(<string>, <string>, <string>)"""
    source = Conversions.StringValue(source)
    fromChars = Conversions.StringValue(fromChars)
    toChars = Conversions.StringValue(toChars)

    # string.maketrans/translate do not handle unicode
    translate = {}
    for from_char, to_char in map(None, fromChars, toChars):
        translate[ord(from_char)] = to_char

    result = reduce(lambda a, b, t=translate: a + (t.get(ord(b), b) or ''),
                    source,
                    '')
    return result
示例#10
0
def Match(context, pattern, arg=None):
    """Do a regular expression match against the argument"""
    if not arg:
        arg = context.node
    arg = Conversions.StringValue(arg)
    bool = re.match(pattern, arg) and boolean.true or boolean.false
    return bool
示例#11
0
def Map(context, funcname, *nodesets):
    """
    Apply the function serially over the given node sets.
    In iteration i, the function is passed N parameters
    where N is the number of argument node sets.  Each
    parameter is a node set of size 1, whose node is
    the ith node of the corresponding argument node set.
    The return value is a node set consisting of a series
    of result-tree nodes, each of which is a text node
    whose value is the string value of the result of the
    ith function invocation.
    Warning: this function uses the implied ordering of the node set
    Based on its implementation as a Python list.  But in reality
    There is no reliable ordering of XPath node sets.
    In other words, this function is voodoo.
    """
    (prefix, local) = ExpandQName(funcname, namespaces=context.processorNss)
    func = (g_extFunctions.get(expanded)
            or CoreFunctions.CoreFunctions.get(expanded, None))
    if not func:
        raise Exception('Dynamically invoked function %s not found.' %
                        funcname)
    flist = [f] * len(nodesets)
    lf = lambda x, f, *args: apply(f, args)
    retlist = apply(map, (lf, flist) + nodesets)

    proc = context.processor
    result_nodeset = []
    for ret in retlist:
        proc.pushResult()
        proc.writers[-1].text(Conversions.StringValue(ret))
        frag = proc.popResult()
        context.rtfs.append(frag)
        result_nodeset.append(frag.childNodes[0])
    return result_nodeset
示例#12
0
def String(context, object=None):
    """Function: <string> string(<object>?)"""
    if type(object) in g_stringTypes:
        return object
    if object is None:
        object = [context.node]
    return Conversions.StringValue(object)
示例#13
0
    def __init__(self, opcode, left, right):
        self._op = opcode

        if isinstance(left, ParsedLiteralExpr):
            self._left = Conversions.NumberValue(left.evaluate(None))
            self._leftLit = 1
        else:
            self._left = left
            self._leftLit = 0

        if isinstance(right, ParsedLiteralExpr):
            self._right = Conversions.NumberValue(right.evaluate(None))
            self._rightLit = 1
        else:
            self._right = right
            self._rightLit = 0
示例#14
0
def SearchRePy20(context, pattern, arg=None):
    """Do a regular expression search against the argument (i.e. get all matches)"""
    if not arg:
        arg = context.node
    arg = Conversions.StringValue(arg)
    proc = context.processor
    matches_nodeset = []
    _re = re.compile(pattern)
    _match = _re.search(arg)
    while _match:
        proc.pushResult()
        proc.writers[-1].startElement('Match', EMPTY_NAMESPACE)
        _groups = _match.groups()
        # .groups() return empty tuple when the pattern did not do grouping
        if not _groups: _groups = tuple(_match.group())
        for group in _groups:
            proc.writers[-1].startElement('Group', EMPTY_NAMESPACE)
            # MatchObject groups return None if unmatched
            # unlike .findall() returning empty strings
            proc.writers[-1].text(group or '')
            proc.writers[-1].endElement('Group')
        proc.writers[-1].endElement('Match')
        frag = proc.popResult()
        context.rtfs.append(frag)
        matches_nodeset.append(frag.childNodes[0])
        _match = _re.search(arg, _match.end())
    return matches_nodeset
示例#15
0
def Substring(context, st, start, end=None):
    """Function: <string> substring(<string>, <number>, <number>?)"""
    st = Conversions.StringValue(st)
    start = Conversions.NumberValue(start)
    if start is NaN:
        return ''
    start = int(round(start))
    start = start > 1 and start - 1 or 0

    if end is None:
        return st[start:]
    end = Conversions.NumberValue(end)
    if start is NaN:
        return st[start:]
    end = int(round(end))
    return st[start:start + end]
示例#16
0
def Concat(context, *args):
    """Function: <string> concat(<string>, <string>, ...)"""
    if len(args) < 1:
        raise RuntimeException(RuntimeException.WRONG_ARGUMENTS, 'concat',
                               _("at least 2 arguments expected"))
    return reduce(lambda a, b, c=context: a + Conversions.StringValue(b),
                  args,
                  '')
示例#17
0
def distinct(context, nodeset):
    if type(nodeset) != type([]):
        raise Exception("'distinct' parameter must be of type node-set!")

    nodes = {}
    for node in nodeset:
        nodes[Conversions.StringValue(node)] = node

    return nodes.values()
示例#18
0
def split(context, arg, delim=None):
    doc = context.node
    while doc.parentNode:
        doc = doc.parentNode

    nodeset = []
    for token in string.split(Conversions.StringValue(arg), delim):
        nodeset.append(doc.createTextNode(token))

    return nodeset
示例#19
0
    def evaluate(self, context):
        if self._leftLit:
            lrt = self._left
        else:
            lrt = Conversions.NumberValue(self._left.evaluate(context))
        if self._rightLit:
            rrt = self._right
        else:
            rrt = Conversions.NumberValue(self._right.evaluate(context))

        if self._op == 0:
            rt = (lrt < rrt)
        elif self._op == 1:
            rt = (lrt <= rrt)
        elif self._op == 2:
            rt = (lrt > rrt)
        elif self._op == 3:
            rt = (lrt >= rrt)
        return rt and boolean.true or boolean.false
示例#20
0
 def evaluate(self, context):
     '''returns a number'''
     lrt = self._left.evaluate(context)
     lrt = Conversions.NumberValue(lrt)
     rrt = self._right.evaluate(context)
     rrt = Conversions.NumberValue(rrt)
     res = 0
     if self._op == 0:
         res = lrt * rrt
     elif self._op == 1:
         if rrt == 0:
             res = NaN
         else:
             res = lrt / rrt
     elif self._op == 2:
         if rrt == 0:
             res = NaN
         else:
             res = lrt % rrt
     return res
示例#21
0
def Id(context, object):
    """Function: <node-set> id(<object>)"""
    id_list = []
    if type(object) != type([]):
        st = Conversions.StringValue(object)
        id_list = string.split(st)
    else:
        for n in object:
            id_list.append(Conversions.StringValue(n))
    rt = []
    for id in id_list:
        doc = context.node.ownerDocument or context.node
        elements = Util.ElementsById(doc.documentElement, id)
        if len(elements) > 1:
            raise RuntimeException(RuntimeException.WRONG_ARGUMENTS, 'id',
                                   _("argument not unique"))
        elif elements:
            # Must be 1
            rt.append(elements[0])
    return rt
示例#22
0
def Floor(context, number):
    """Function: <number> floor(<number>)"""
    number = Conversions.NumberValue(number)
    #if type(number) in g_stringTypes:
    #    number = string.atof(number)
    if int(number) == number:
        return number
    elif number < 0:
        return int(number) - 1
    else:
        return int(number)
示例#23
0
def Ceiling(context, number):
    """Function: <number> ceiling(<number>)"""
    number = Conversions.NumberValue(number)
    #if type(number) in g_stringTypes:
    #    number = string.atof(number)
    if int(number) == number:
        return number
    elif number > 0:
        return int(number) + 1
    else:
        return int(number)
示例#24
0
def Lang(context, lang):
    """Function: <boolean> lang(<string>)"""
    lang = string.upper(Conversions.StringValue(lang))
    node = context.node
    while node:
        lang_attr = filter(lambda x: x.name == 'xml:lang' and x.value,
                           node.attributes.values())
        value = lang_attr and lang_attr[0].nodeValue or None
        if value:
            # See if there is a suffix
            index = string.find(value, '-')
            if index != -1:
                value = value[:index]
            value = string.upper(value)
            return value == lang and boolean.true or boolean.false
        node = node.nodeType == Node.ATTRIBUTE_NODE and node.ownerElement or node.parentNode
    return boolean.false
示例#25
0
def SearchRe(context, pattern, arg=None):
    """Do a regular expression search against the argument (i.e. get all matches)"""
    if not arg:
        arg = context.node
    arg = Conversions.StringValue(arg)
    matches = re.findall(pattern, arg)
    proc = context.processor
    matches_nodeset = []
    for groups in matches:
        proc.pushResult()
        proc.writers[-1].startElement('Match', EMPTY_NAMESPACE)
        if type(groups) != type(()):
            groups = (groups, )
        for group in groups:
            proc.writers[-1].startElement('Group', EMPTY_NAMESPACE)
            proc.writers[-1].text(group)
            proc.writers[-1].endElement('Group')
        proc.writers[-1].endElement('Match')
        frag = proc.popResult()
        context.rtfs.append(frag)
        matches_nodeset.append(frag.childNodes[0])
    return matches_nodeset
示例#26
0
 def filter(self, nodeList, context, reverse):
     if self._length:
         state = context.copyNodePosSize()
         for pred in self._predicates:
             size = len(nodeList)
             ctr = 0
             current = nodeList
             nodeList = []
             for node in current:
                 position = (reverse and size - ctr) or (ctr + 1)
                 context.setNodePosSize((node, position, size))
                 res = pred.evaluate(context)
                 if type(res) in NumberTypes:
                     # This must be separate to prevent falling into
                     # the boolean check.
                     if res == position:
                         nodeList.append(node)
                 elif Conversions.BooleanValue(res):
                     nodeList.append(node)
                 ctr = ctr + 1
         context.setNodePosSize(state)
     return nodeList
示例#27
0
def Round(context, number):
    """Function: <number> round(<number>)"""
    number = Conversions.NumberValue(number)
    return round(number, 0)
示例#28
0
def Sum(context, nodeSet):
    """Function: <number> sum(<node-set>)"""
    nns = map(lambda x: Conversions.NumberValue(x), nodeSet)
    return reduce(lambda x, y: x + y, nns, 0)
示例#29
0
def Number(context, object=None):
    """Function: <number> number(<object>?)"""
    if object is None:
        object = [context.node]
    return Conversions.NumberValue(object)
示例#30
0
def Not(context, object):
    """Function: <boolean> not(<boolean>)"""
    return (not Conversions.BooleanValue(object)
            and boolean.true) or boolean.false