예제 #1
0
파일: html.py 프로젝트: mredar/amara
 def insertText(self, data, insertBefore=None):
     """Insert data as text in the current node, positioned before the 
     start of node insertBefore or to the end of the node's text.
     """
     if insertBefore:
         self.insertBefore(tree.text(data), insertBefore)
     else:
         self.xml_append(tree.text(data))
예제 #2
0
파일: html.py 프로젝트: distobj/amara
 def insertText(self, data, insertBefore=None):
     """Insert data as text in the current node, positioned before the 
     start of node insertBefore or to the end of the node's text.
     """
     if insertBefore:
         self.insertBefore(tree.text(data), insertBefore)
     else:
         self.xml_append(tree.text(data))
예제 #3
0
def replace_function(context, string, search, replace):
    """
    The str:replace function converts a string to a node-set, with
    each instance of a substring from a given list (obtained from the
    string-values of nodes in the second argument) replaced by the
    node at the corresponding position of the node-set given as the
    third argument. Unreplaced substrings become text nodes.

    The second and third arguments can be any type of object; if
    either is not a node-set, it is treated as if it were a node-set
    of just one text node, formed from the object's string-value.

    Attribute and namespace nodes in the replacement set are
    erroneous but are treated as empty text nodes.

    All occurrences of the longest substrings are replaced first,
    and once a replacement is made, that span of the original string
    is no longer eligible for future replacements.

    An empty search string matches between every character of the
    original string.

    See http://exslt.org/str/functions/replace/str.replace.html for details.
    """
    #FIXME: http://www.exslt.org/str/functions/replace/ doesn't say we have
    #to convert the first arg to a string, but should we, anyway?
    #If not, we should at least check and flag non-strings with a clear error?
    # prepare a list of strings to search for (based on searchNodeSet)
    string = string.evaluate_as_string(context)
    search = search.evaluate(context)
    replace = replace.evaluate(context)
    if isinstance(search, datatypes.nodeset):
        search = map(datatypes.string, search)
    else:
        search = [datatypes.string(search)]
    if isinstance(replace, datatypes.nodeset):
        # use `replace` but replace attr, ns nodes with empty text nodes
        for index, node in enumerate(replace):
            if isinstance(node, (tree.attribute, tree.namespace)):
                replace[index] = tree.text(u'')
    else:
        replace = [tree.text(datatypes.string(replace))]
    # Unpaired search patterns are to be deleted (replacement is None)
    replace = itertools.chain(replace, itertools.repeat(None))
    # Sort the tuples in ascending order by length of string.
    # So that the longest search strings will be replaced first,
    replacements = zip(search, replace, itertools.imap(len, search))
    replacements.sort(key=operator.itemgetter(2), reverse=True)

    # generate a result tree fragment
    context.push_tree_writer(context.instruction.baseUri)
    _replace(context, string, *replacements)
    writer = context.pop_writer()
    rtf = writer.get_result()
    return datatypes.nodeset(rtf.xml_children)
예제 #4
0
파일: strings.py 프로젝트: abed-hawa/amara
def replace_function(context, string, search, replace):
    """
    The str:replace function converts a string to a node-set, with
    each instance of a substring from a given list (obtained from the
    string-values of nodes in the second argument) replaced by the
    node at the corresponding position of the node-set given as the
    third argument. Unreplaced substrings become text nodes.

    The second and third arguments can be any type of object; if
    either is not a node-set, it is treated as if it were a node-set
    of just one text node, formed from the object's string-value.

    Attribute and namespace nodes in the replacement set are
    erroneous but are treated as empty text nodes.

    All occurrences of the longest substrings are replaced first,
    and once a replacement is made, that span of the original string
    is no longer eligible for future replacements.

    An empty search string matches between every character of the
    original string.

    See http://exslt.org/str/functions/replace/str.replace.html for details.
    """
    # FIXME: http://www.exslt.org/str/functions/replace/ doesn't say we have
    # to convert the first arg to a string, but should we, anyway?
    # If not, we should at least check and flag non-strings with a clear error?
    # prepare a list of strings to search for (based on searchNodeSet)
    string = string.evaluate_as_string(context)
    search = search.evaluate(context)
    replace = replace.evaluate(context)
    if isinstance(search, datatypes.nodeset):
        search = map(datatypes.string, search)
    else:
        search = [datatypes.string(search)]
    if isinstance(replace, datatypes.nodeset):
        # use `replace` but replace attr, ns nodes with empty text nodes
        for index, node in enumerate(replace):
            if isinstance(node, (tree.attribute, tree.namespace)):
                replace[index] = tree.text(u"")
    else:
        replace = [tree.text(datatypes.string(replace))]
    # Unpaired search patterns are to be deleted (replacement is None)
    replace = itertools.chain(replace, itertools.repeat(None))
    # Sort the tuples in ascending order by length of string.
    # So that the longest search strings will be replaced first,
    replacements = zip(search, replace, itertools.imap(len, search))
    replacements.sort(key=operator.itemgetter(2), reverse=True)

    # generate a result tree fragment
    context.push_tree_writer(context.instruction.baseUri)
    _replace(context, string, *replacements)
    writer = context.pop_writer()
    rtf = writer.get_result()
    return datatypes.nodeset(rtf.xml_children)
예제 #5
0
 def pagelink(self, on, pagename="", page=None, **kw):
     FormatterBase.pagelink(self, on, pagename, page, **kw)
     if page is None:
         page = Page(self.request, pagename, formatter=self)
     link_text = page.link_to(self.request, on=on, **kw)
     self._curr.xml_append(tree.text(U(link_text)))
     return ""
예제 #6
0
 def pagelink(self, on, pagename='', page=None, **kw):
     FormatterBase.pagelink(self, on, pagename, page, **kw)
     if page is None:
         page = Page(self.request, pagename, formatter=self)
     link_text = page.link_to(self.request, on=on, **kw)
     self._curr.xml_append(tree.text(U(link_text)))
     return ''
예제 #7
0
 def test_chardata_unb(self):
     spam = tree.text(u'Spam')
     self.assertEqual(spam.xml_value, u'Spam')
     self.assertEqual(len(spam.xml_value), 4)
     self.assertEqual(spam.xml_value[1:3], u'pa')
     spam.xml_value += u' eggs'
     self.assertEqual(spam.xml_value, u'Spam eggs')
예제 #8
0
 def list_services(self, ident=None):
     document = tree.entity()
     services = document.xml_append(tree.element(None, 'services'))
     for path, service in sorted(self._registered_services.iteritems()):
         if ident is not None and service.ident != ident:
             continue
         service_node = services.xml_append(tree.element(None, 'service'))
         service_node.xml_attributes['ident'] = service.ident
         E = service_node.xml_append(tree.element(None, 'path'))
         template = service.template
         if template is not None:
             E.xml_attributes["template"] = service.template.template
         E.xml_append(tree.text(path))
         E = service_node.xml_append(tree.element(None, 'description'))
         E.xml_append(tree.text(service.doc))
     return document
예제 #9
0
 def test_chardata_unb(self):
     spam = tree.text(u'Spam')
     self.assertEqual(spam.xml_value, u'Spam')
     self.assertEqual(len(spam.xml_value), 4)
     self.assertEqual(spam.xml_value[1:3], u'pa')
     spam.xml_value += u' eggs'
     self.assertEqual(spam.xml_value, u'Spam eggs')
예제 #10
0
파일: registry.py 프로젝트: dpla/akara
 def list_services(self, ident=None):
     document = tree.entity()
     services = document.xml_append(tree.element(None, 'services'))
     for path, service in sorted(self._registered_services.iteritems()):
         if ident is not None and service.ident != ident:
             continue
         service_node = services.xml_append(tree.element(None, 'service'))
         service_node.xml_attributes['ident'] = service.ident
         E = service_node.xml_append(tree.element(None, 'path'))
         template = service.template
         if template is not None:
             E.xml_attributes["template"] = service.template.template
         E.xml_append(tree.text(path))
         E = service_node.xml_append(tree.element(None, 'description'))
         E.xml_append(tree.text(service.doc))
     return document
예제 #11
0
파일: nodes.py 프로젝트: abed-hawa/amara
 def xml_append(self, obj):
     # Can't really rely on super here
     base_class = {tree.element.xml_type: tree.element, tree.entity.xml_type: tree.entity}[self.xml_type]
     if isinstance(obj, str):
         base_class.xml_append(self, tree.text(obj.decode(self.factory_entity.xml_encoding)))
     elif isinstance(obj, unicode):
         base_class.xml_append(self, tree.text(obj))
     elif isinstance(obj, tree.node):
         base_class.xml_append(self, obj)
     elif isinstance(obj, E):
         buf = StringIO()
         w = structwriter(indent=u"yes", stream=buf)
         w.feed(obj)
         self.xml_append_fragment(buf.getvalue())
     else:
         raise TypeError
     return
예제 #12
0
파일: nodes.py 프로젝트: mredar/amara
 def xml_append(self, obj):
     #Can't really rely on super here
     base_class = {tree.element.xml_type: tree.element, tree.entity.xml_type: tree.entity}[self.xml_type]
     if isinstance(obj, str):
         base_class.xml_append(self, tree.text(obj.decode(self.factory_entity.xml_encoding)))
     elif isinstance(obj, unicode):
         base_class.xml_append(self, tree.text(obj))
     elif isinstance(obj, tree.node):
         base_class.xml_append(self, obj)
     elif isinstance(obj, E):
         buf = StringIO()
         w = structwriter(indent=u"yes", stream=buf)
         w.feed(obj)
         self.xml_append_fragment(buf.getvalue())
     else:
         raise TypeError
     return
예제 #13
0
 def _addTextElem(self, target, elemName, text):
     """
     Creates an element of the name elemName and adds a text node to it
     with the nodeValue of text. The new element is then added as a child
     to the element target.
     """
     newElement = tree.element(None, elemName)
     newElement.xml_append(tree.text(text))
     target.xml_append(newElement)
예제 #14
0
 def _addTextElem(self, target, elemName, text):
     """
     Creates an element of the name elemName and adds a text node to it
     with the nodeValue of text. The new element is then added as a child
     to the element target.
     """
     newElement = tree.element(None, elemName)
     newElement.xml_append(tree.text(text))
     target.xml_append(newElement)
예제 #15
0
 def test_create_new_doc_comment(self):
     EXPECTED = '<A a="b">One</A><!--This is easy-->'
     doc = tree.entity()
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
예제 #16
0
 def test_create_new_doc_comment(self):
     EXPECTED = '<A a="b">One</A><!--This is easy-->'
     doc = tree.entity()
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     self.compare_output(doc, XMLDECL + EXPECTED)
     return
예제 #17
0
 def test_create_new_doc_pi(self):
     EXPECTED = '<?xml-stylesheet href="classic.xsl" type="text/xml"?><A a="b">One</A>'
     doc = tree.entity()
     doc.xml_append(tree.processing_instruction(u'xml-stylesheet', 
                                                u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
예제 #18
0
 def test_create_new_doc_attr_factory(self):
     EXPECTED = '<A a="b">One</A>'
     doc = tree.entity()
     A = tree.element(None, u'A')
     
     new_attr = A.xml_attribute_factory(None, u'a', u'b')
     A.xml_attributes.setnode(new_attr)
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
예제 #19
0
    def test_create_new_doc_attr_factory(self):
        EXPECTED = '<A a="b">One</A>'
        doc = tree.entity()
        A = tree.element(None, u'A')

        new_attr = A.xml_attribute_factory(None, u'a', u'b')
        A.xml_attributes.setnode(new_attr)
        A.xml_append(tree.text(u'One'))
        doc.xml_append(A)
        self.compare_output(doc, XMLDECL + EXPECTED)
        return
예제 #20
0
 def test_create_new_doc_pi(self):
     EXPECTED = '<?xml-stylesheet href="classic.xsl" type="text/xml"?><A a="b">One</A>'
     doc = tree.entity()
     doc.xml_append(
         tree.processing_instruction(u'xml-stylesheet',
                                     u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL + EXPECTED)
     return
예제 #21
0
파일: util.py 프로젝트: abed-hawa/amara
def paramvalue(obj):
    """
    Try to convert a Python object into an XPath data model value

    returns the value if successful, else None
    """
    if isinstance(obj, datatypes.xpathobject):
        return obj
    if isinstance(obj, unicode):
        return datatypes.string(obj)
    elif isinstance(obj, str):
        try:
            obj = obj.decode("utf-8")
        except UnicodeError:
            return None
        else:
            return datatypes.string(obj)
    elif isinstance(obj, bool):  # <bool> is subclasses of <int>, test first
        return datatypes.TRUE if obj else datatypes.FALSE
    elif isinstance(obj, (int, long, float)):
        return datatypes.number(obj)
    elif isinstance(obj, tree.node):
        return obj
    # NOTE: At one time (WSGI.xml days) this attemped to be smart and handle
    # all iterables but this would mean blindly dealing with dangerous
    # creatures, such as sockets. So now it's more conservative and sticks to
    # just list & tuple.
    elif isinstance(obj, (list, tuple)):
        # We can only use the list if the items are all nodes or all strings.
        # Strings are converted to a nodeset of text nodes.
        for item in obj:
            if not isinstance(item, (str, unicode)):
                break
        else:
            # We need to use an entity to preserve ordering
            entity = tree.entity()
            for item in obj:
                if isinstance(item, str):
                    try:
                        item = unicode(item, "utf8")
                    except UnicodeError:
                        return None
                entity.xml_append(tree.text(item))
            return datatypes.nodeset(entity.xml_children)
        # We can only use the list if all the items are nodes.
        for item in obj:
            if not isinstance(item, tree.node):
                return None
        return datatypes.nodeset(obj)
    else:
        return None
예제 #22
0
def paramvalue(obj):
    """
    Try to convert a Python object into an XPath data model value

    returns the value if successful, else None
    """
    if isinstance(obj, datatypes.xpathobject):
        return obj
    if isinstance(obj, unicode):
        return datatypes.string(obj)
    elif isinstance(obj, str):
        try:
            obj = obj.decode('utf-8')
        except UnicodeError:
            return None
        else:
            return datatypes.string(obj)
    elif isinstance(obj, bool): # <bool> is subclasses of <int>, test first
        return datatypes.TRUE if obj else datatypes.FALSE
    elif isinstance(obj, (int, long, float)):
        return datatypes.number(obj)
    elif isinstance(obj, tree.node):
        return obj
    # NOTE: At one time (WSGI.xml days) this attemped to be smart and handle
    # all iterables but this would mean blindly dealing with dangerous
    # creatures, such as sockets. So now it's more conservative and sticks to
    # just list & tuple.
    elif isinstance(obj, (list, tuple)):
        # We can only use the list if the items are all nodes or all strings.
        # Strings are converted to a nodeset of text nodes.
        for item in obj:
            if not isinstance(item, (str, unicode)):
                break
        else:
            # We need to use an entity to preserve ordering
            entity = tree.entity()
            for item in obj:
                if isinstance(item, str):
                    try:
                        item = unicode(item, 'utf8')
                    except UnicodeError:
                        return None
                entity.xml_append(tree.text(item))
            return datatypes.nodeset(entity.xml_children)
        # We can only use the list if all the items are nodes.
        for item in obj:
            if not isinstance(item, tree.node):
                return None
        return datatypes.nodeset(obj)
    else:
        return None
예제 #23
0
    def text(self, text, **kw):
        if text == u"\\n":
            srcText = u"\n"
        else:
            srcText = text

        if srcText and self._isInsidePreformatted():
            # 4Suite version used CDATASection nodes.  Don't bother
            self.cur.xml_last_child.xml_append(tree.text(srcText))

        elif self.cur.xml_qname in self.wrap_text_in_para:
            """
            If we already wrapped one text item in a para, we should add to that para
            and not create a new one. Another question is if we should add a space?
            """
            if self.cur.xml_last_child is not None and self.cur.xml_last_child.xml_qname == u'para':
                self.cur.xml_last_child.xml_append(tree.text(srcText))
            else:
                self.paragraph(1)
                self.text(text)
                self.paragraph(0)
        else:
            self.cur.xml_append(tree.text(srcText))
        return ""
예제 #24
0
    def text(self, text, **kw):
        if text == u"\\n":
            srcText = u"\n"
        else:
            srcText = text

        if srcText and self._isInsidePreformatted():
            # 4Suite version used CDATASection nodes.  Don't bother
            self.cur.xml_last_child.xml_append(tree.text(srcText))

        elif self.cur.xml_qname in self.wrap_text_in_para:
            """
            If we already wrapped one text item in a para, we should add to that para
            and not create a new one. Another question is if we should add a space?
            """
            if self.cur.xml_last_child is not None and self.cur.xml_last_child.xml_qname == u"para":
                self.cur.xml_last_child.xml_append(tree.text(srcText))
            else:
                self.paragraph(1)
                self.text(text)
                self.paragraph(0)
        else:
            self.cur.xml_append(tree.text(srcText))
        return ""
예제 #25
0
 def test_reading_building(self):
     doc = tree.entity()
     doc.xml_append(tree.processing_instruction(u'xml-stylesheet', 
                                                u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     doc2 = amara.parse('docs/whatsnew_doc1.xml')
     output1 = cStringIO.StringIO()        
     output2 = cStringIO.StringIO()        
     xml_print(doc, stream=output1)
     xml_print(doc2, stream=output2)
     self.assertEqual(output1.getvalue(), output2.getvalue())
     return
예제 #26
0
파일: __init__.py 프로젝트: abed-hawa/amara
 def set_default(self, node):
     #XXX: Should be able to reuse named_node_test function
     #What prefix to use
     for prefix, ns in node.xml_namespaces.items():
         if ns == self.ns and prefix:
             qname = prefix + u':' + self.local
             break
     else:
         #No prefix: just hijack the default namespace
         qname = self.local
     ownerdoc = node.xml_select(u'/')[0]
     eclass = ownerdoc.eclass(self.ns, self.local)
     new_elem = eclass(self.ns, qname)
     new_elem.xml_append(tree.text(self.default))
     node.xml_append(new_elem)
     return
예제 #27
0
파일: __init__.py 프로젝트: mredar/amara
 def set_default(self, node):
     #XXX: Should be able to reuse named_node_test function
     #What prefix to use
     for prefix, ns in node.xml_namespaces.items():
         if ns == self.ns and prefix:
             qname = prefix + u':' + self.local
             break
     else:
         #No prefix: just hijack the default namespace
         qname = self.local
     ownerdoc = node.xml_select(u'/')[0]
     eclass = ownerdoc.eclass(self.ns, self.local)
     new_elem = eclass(self.ns, qname)
     new_elem.xml_append(tree.text(self.default))
     node.xml_append(new_elem)
     return
예제 #28
0
 def test_reading_building(self):
     doc = tree.entity()
     doc.xml_append(
         tree.processing_instruction(u'xml-stylesheet',
                                     u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     doc2 = amara.parse('docs/whatsnew_doc1.xml')
     output1 = cStringIO.StringIO()
     output2 = cStringIO.StringIO()
     xml_print(doc, stream=output1)
     xml_print(doc2, stream=output2)
     self.assertEqual(output1.getvalue(), output2.getvalue())
     return
예제 #29
0
파일: dynamic.py 프로젝트: mredar/amara
def _map(context, nodeset, expr):
    focus = context.node, context.position, context.size
    context.size = len(nodeset)
    position = 1

    inputs = iter(nodeset)
    return_type = None
    result = set()
    for node in inputs:
        context.node = node
        context.position = position
        position += 1

        try:
            obj = expr.evaluate(context)
        except:
            lines = traceback.format_exception(*sys.exc_info())
            lines[:1] = [("Runtime error in XPath expression '%(expr)s', "
                          "lower-level traceback:\n") % {
                              'expr': string
                          }]
            context.processor.warning(''.join(lines))
        else:
            if not return_type:
                if isinstance(obj, datatypes.nodeset):
                    tag_name = None
                elif isinstance(obj, datatypes.number):
                    tag_name = 'exsl:number'
                    converter = datatypes.string
                elif isinstance(obj, datatypes.boolean):
                    tag_name = 'exsl:boolean'
                    converter = lambda obj: u'true' if obj else u''
                else:
                    tag_name = 'exsl:string'
                    converter = datatypes.string
                return_type = True
            if tag_name:
                E = tree.element(EXSL_COMMON_NS, tag_name)
                E.xml_append(tree.text(converter(obj)))
                result.add(E)
            else:
                result.update(obj)
    context.node, context.position, context.size = focus
    return datatypes.nodeset(result)
예제 #30
0
 def trim(node, count):
     newnode = copy(node)
     for child in node.xml_children:
         if count >= maxcount:
             break
         words = len(child.xml_select(u'string(.)').split())
         if count + words < maxcount:
             newnode.xml_append(deepcopy(child))
             count += words
         else:
             if isinstance(child, tree.text):
                 words_required = maxcount - count
                 chunk = child.xml_value.rsplit(None,
                                                words - words_required)[0]
                 newnode.xml_append(tree.text(chunk))
             else:
                 newnode.xml_append(trim(child, count))
             count = maxcount
     return newnode
예제 #31
0
파일: util.py 프로젝트: abed-hawa/amara
 def trim(node, count):
     newnode = copy(node)
     for child in node.xml_children:
         if count >= maxcount:
             break
         words = len(child.xml_select(u'string(.)').split())
         if count + words < maxcount:
             newnode.xml_append(deepcopy(child))
             count += words
         else:
             if isinstance(child, tree.text):
                 words_required = maxcount - count
                 chunk = child.xml_value.rsplit(None, 
                                                words-words_required)[0]
                 newnode.xml_append(tree.text(chunk))
             else:
                 newnode.xml_append(trim(child, count))
             count = maxcount
     return newnode
예제 #32
0
파일: common.py 프로젝트: mredar/amara
def nodeset_function(context, arg0):
    """
    The purpose of the exsl:node-set function is to return a node-set from a
    result tree fragment. If the argument is a node-set already, it is simply
    returned as is. If the argument to exsl:node-set is not a node-set or a
    result tree fragment, then it is converted to a string as by the string()
    function, and the function returns a node-set consisting of a single text
    node with that string value.

    The exsl:node-set function does not have side-effects: the result tree
    fragment used as an argument is still available as a result tree fragment
    after it is passed as an argument to exsl:node-set.
    """
    obj = arg0.evaluate(context)
    if not isinstance(obj, datatypes.nodeset):
        if not isinstance(obj, tree.entity):
            obj = (tree.text(datatypes.string(obj)), )
        obj = datatypes.nodeset([obj])
    return obj
예제 #33
0
파일: common.py 프로젝트: abed-hawa/amara
def nodeset_function(context, arg0):
    """
    The purpose of the exsl:node-set function is to return a node-set from a
    result tree fragment. If the argument is a node-set already, it is simply
    returned as is. If the argument to exsl:node-set is not a node-set or a
    result tree fragment, then it is converted to a string as by the string()
    function, and the function returns a node-set consisting of a single text
    node with that string value.

    The exsl:node-set function does not have side-effects: the result tree
    fragment used as an argument is still available as a result tree fragment
    after it is passed as an argument to exsl:node-set.
    """
    obj = arg0.evaluate(context)
    if not isinstance(obj, datatypes.nodeset):
        if not isinstance(obj, tree.entity):
            obj = (tree.text(datatypes.string(obj)),)
        obj = datatypes.nodeset([obj])
    return obj
예제 #34
0
파일: dynamic.py 프로젝트: abed-hawa/amara
def _map(context, nodeset, expr):
    focus = context.node, context.position, context.size
    context.size = len(nodeset)
    position = 1

    inputs = iter(nodeset)
    return_type = None
    result = set()
    for node in inputs:
        context.node = node
        context.position = position
        position += 1

        try:
            obj = expr.evaluate(context)
        except:
            lines = traceback.format_exception(*sys.exc_info())
            lines[:1] = [("Runtime error in XPath expression '%(expr)s', "
                            "lower-level traceback:\n") % {'expr': string}]
            context.processor.warning(''.join(lines))
        else:
            if not return_type:
                if isinstance(obj, datatypes.nodeset):
                    tag_name = None
                elif isinstance(obj, datatypes.number):
                    tag_name = 'exsl:number'
                    converter = datatypes.string
                elif isinstance(obj, datatypes.boolean):
                    tag_name = 'exsl:boolean'
                    converter = lambda obj: u'true' if obj else u''
                else:
                    tag_name = 'exsl:string'
                    converter = datatypes.string
                return_type = True
            if tag_name:
                E = tree.element(EXSL_COMMON_NS, tag_name)
                E.xml_append(tree.text(converter(obj)))
                result.add(E)
            else:
                result.update(obj)
    context.node, context.position, context.size = focus
    return datatypes.nodeset(result)
예제 #35
0
def process_pre_poem(node):
    '''
    >>> X = ['<div>', '<pre>The red cap chiefs stack up their wealth,', 'Shards of what once was bred in bone.', '', 'Church tales of wandering accursed&#8212;', 'It\'s forty years full fifty times;', '</pre>', '</div>']
    >>> X = '\n'.join(X)
    >>> doc = parse(X)
    >>> process_pre_poem(doc.xml_first_child)
    >>> doc.xml_write()
    <?xml version="1.0" encoding="UTF-8"?>
<div>
<p>The red cap chiefs stack up their wealth,<br/>Shards of what once was bred in bone.<br/></p><p>Church tales of wandering accursed—<br/>It's forty years full fifty times;<br/><br/></p>
</div>
    '''
    for pre in node.xml_select(u'.//pre'):
        ptext = U(pre)
        if pre.xml_first_child:
            pre.xml_remove(pre.xml_first_child)
        for stanza in ptext.split(u'\n\n'):
            p = element(None, u'p')
            pre.xml_append(p)
            for line in stanza.split(u'\n'):
                p.xml_append(text(line))
                p.xml_append(element(None, u'br'))
        unwrap(pre)
    return
예제 #36
0
 def attachment_drawing(self, url, text, **kw):
     self._elem(u"attachmentimage", on)
     self._curr.xml_attributes[None, u"href"] = U(url)
     self._curr.xml_append(tree.text(U(text)))
     self._elem(u"attachmentimage", off)
     return ""
예제 #37
0
 def text(self, text, **kw):
     self._curr.xml_append(tree.text(text))
     return ''
예제 #38
0
 def rule(self, size=0, **kw):
     e = tree.element(None, u'br')  # <hr/> not supported in stylebook
     e.xml_append(tree.text((u"-" * 78)))
     self._curr.xml_append(e)
     return ''
예제 #39
0
 def attachment_drawing(self, url, text, **kw):
     self._elem(u'attachmentimage', on)
     self._curr.xml_attributes[None, u'href'] = U(url)
     self._curr.xml_append(tree.text(U(text)))
     self._elem(u'attachmentimage', off)
     return ''
예제 #40
0
 def smiley(self, text):
     self._curr.xml_append(tree.text(U(text)))
     return ''
예제 #41
0
    FALSE,
    # number literals (for special values)
    NOT_A_NUMBER,
    POSITIVE_INFINITY,
    NEGATIVE_INFINITY,
    # nodeset literals
    nodeset_literal,
    EMPTY_NODESET,
)

from amara.xpath import context
from test_expressions import DOC
default_context = context(DOC, 1, 1)

EGG1 = tree.element(None, 'egg1')
EGG1.xml_append(tree.text('egg1'))
EGG2 = tree.element(None, 'egg2')
EGG2.xml_append(tree.text('egg2'))

NUM = tree.element(None, 'num')
NUM0 = tree.attribute(None, 'num0', '0')
NUM.xml_attributes.setnode(NUM0)
NUM2 = tree.attribute(None, 'num2', '2')
NUM.xml_attributes.setnode(NUM0)
NUM4 = tree.attribute(None, 'num4', '4')
NUM.xml_attributes.setnode(NUM0)
NUM31 = tree.attribute(None, 'num31', '31')
NUM.xml_attributes.setnode(NUM0)


def test_or_expr():
예제 #42
0
    NOT_A_NUMBER,
    POSITIVE_INFINITY,
    NEGATIVE_INFINITY,
    # nodeset literals
    nodeset_literal,
    EMPTY_NODESET,
)

from amara.xpath import context
from test_expressions import DOC

default_context = context(DOC, 1, 1)


EGG1 = tree.element(None, "egg1")
EGG1.xml_append(tree.text("egg1"))
EGG2 = tree.element(None, "egg2")
EGG2.xml_append(tree.text("egg2"))

NUM = tree.element(None, "num")
NUM0 = tree.attribute(None, "num0", "0")
NUM.xml_attributes.setnode(NUM0)
NUM2 = tree.attribute(None, "num2", "2")
NUM.xml_attributes.setnode(NUM0)
NUM4 = tree.attribute(None, "num4", "4")
NUM.xml_attributes.setnode(NUM0)
NUM31 = tree.attribute(None, "num31", "31")
NUM.xml_attributes.setnode(NUM0)


def test_or_expr():
예제 #43
0
 def text(self, text, **kw):
     self._curr.xml_append(tree.text(text))
     return ""
예제 #44
0
 def rule(self, size=0, **kw):
     e = tree.element(None, u"br")  # <hr/> not supported in stylebook
     e.xml_append(tree.text((u"-" * 78)))
     self._curr.xml_append(e)
     return ""
예제 #45
0
    CHILD1,
    CHILD2,
    CHILD3,
    LCHILD1,
    LCHILD2)

# contexts for nodeset {CHILD1, CHILD2, CHILD3}
CONTEXT1 = context(CHILD1, 1, 3)
CONTEXT2 = context(CHILD2, 2, 3)
# contexts for nodeset {LCHILD1, LCHILD2, NONASCIIQNAME}
CONTEXTLANG1 = context(LCHILD1, 1, 3)
CONTEXTLANG2 = context(LCHILD2, 2, 3)

DOC = tree.entity()
EGG1 = DOC.xml_append(tree.element(None, 'egg0'))
EGG1.xml_append(tree.text('0'))
EGG2 = DOC.xml_append(tree.element(None, 'egg1'))
EGG2.xml_append(tree.text('1'))
EGG3 = DOC.xml_append(tree.element(None, 'egg0'))
EGG3.xml_append(tree.text('0'))
EGG4 = DOC.xml_append(tree.element(None, 'egg1'))
EGG4.xml_append(tree.text('1'))
EGG5 = DOC.xml_append(tree.element(None, 'egg0'))
EGG5.xml_append(tree.text('0'))

from amara.xpath.expressions.functioncalls import function_call


def test_last_function():
    for context in (CONTEXT1, CONTEXT2):
        result = function_call('last', ()).evaluate_as_number(context)
예제 #46
0
파일: test_parser.py 프로젝트: mredar/amara
#     <x>
#       <y>a</y>
#     </x>
#   </element>
#   <element>
#     <x>
#       <y>z</y>
#     </x>
#   </element>
# </elements>
ELEMENTS = tree.entity().xml_append(tree.element(None, 'elements'))
for cdata in ('a', 'z'):
    node = ELEMENTS.xml_append(tree.element(None, 'element'))
    node = node.xml_append(tree.element(None, 'x'))
    node = node.xml_append(tree.element(None, 'y'))
    node.xml_append(tree.text(cdata))
del node, cdata
CONTEXT_ELEMENT = context(ELEMENTS, 1, 1)
ELEMENT1, ELEMENT2 = ELEMENTS

from amara.xpath.parser import parse


def _run_parser_pass(test_cases):
    for args, expected, ctx in test_cases:
        result = parse(*args).evaluate(ctx)
        if hasattr(expected, "isnan") and expected.isnan():
            assert result.isnan()
            continue
        if isinstance(expected, list):
            # convert nodesets to lists to prevent XPath-style nodeset compares
예제 #47
0
 def code_line(self, on):
     if on:
         self.cur.xml_append(tree.text(u"\n"))
     return ""
예제 #48
0
</catalog>'''

EXTRACT_AUTHORS_PAT = r'(\s*By\s*)|(\s*,\s*)|(\s*and\s*)'
EXTRACT_AUTHORS_PAT_GROUPS = 4

doc = amara.parse(SOURCE)
for author_node in doc.xml_select(u'/catalog/book/authors'):
    authors = re.split(EXTRACT_AUTHORS_PAT, U(author_node))
    for n in author_node.xml_children: author_node.xml_remove(n)
    #Collect the regex match into the regex-defined groups
    for i, subenum in groupby(enumerate(authors), lambda i: i[0]//EXTRACT_AUTHORS_PAT_GROUPS):
        matchgroup = [ group for i, group in subenum ]
        if matchgroup[0]:
            link = element(None, u'a')
            link.xml_attributes[None, u'href'] = 'http://example.org'
            link.xml_append(text(matchgroup[0]))
            author_node.xml_append(link)
        for match in matchgroup[1:]:
            if match:
                author_node.xml_append(text(match))

doc.xml_write()
print

#The following variation contributed by Luis Miguel Morillas:

SOURCE = '''<catalog>
 <book>
    <title>Spam for Supper</title>
       By A.X. Ham and Franco Bacon
   <info> Other info</info>
예제 #49
0
 def code_line(self, on):
     if on:
         self.cur.xml_append(tree.text(u'\n'))
     return ''
예제 #50
0
    # number literals (for special values)
    NOT_A_NUMBER, POSITIVE_INFINITY, NEGATIVE_INFINITY,
    # nodeset literals
    nodeset_literal, ROOT, CHILD1, CHILD2, CHILD3, LCHILD1, LCHILD2
    )

# contexts for nodeset {CHILD1, CHILD2, CHILD3}
CONTEXT1 = context(CHILD1, 1, 3)
CONTEXT2 = context(CHILD2, 2, 3)
# contexts for nodeset {LCHILD1, LCHILD2, NONASCIIQNAME}
CONTEXTLANG1 = context(LCHILD1, 1, 3)
CONTEXTLANG2 = context(LCHILD2, 2, 3)

DOC = tree.entity()
EGG1 = DOC.xml_append(tree.element(None, 'egg0'))
EGG1.xml_append(tree.text('0'))
EGG2 = DOC.xml_append(tree.element(None, 'egg1'))
EGG2.xml_append(tree.text('1'))
EGG3 = DOC.xml_append(tree.element(None, 'egg0'))
EGG3.xml_append(tree.text('0'))
EGG4 = DOC.xml_append(tree.element(None, 'egg1'))
EGG4.xml_append(tree.text('1'))
EGG5 = DOC.xml_append(tree.element(None, 'egg0'))
EGG5.xml_append(tree.text('0'))


from amara.xpath.expressions.functioncalls import function_call

def test_last_function():
    for context in (CONTEXT1, CONTEXT2):
        result = function_call('last', ()).evaluate_as_number(context)
예제 #51
0
 def smiley(self, text):
     self._curr.xml_append(tree.text(U(text)))
     return ""