Ejemplo n.º 1
0
def test_namespaces():
    element = Element("test", {
        "xmlns": "default ns",
        "xmlns:junk-ns0": "junk-ns value 0",
        "xmlns:junk-ns1": "junk-ns value 1",
        "py:pyattr": "py value",
        "attr": "a new attr",
    })

    ns = namespaces(element)
    expected = {
        "": "default ns",
        "junk-ns0": "junk-ns value 0",
        "junk-ns1": "junk-ns value 1",
    }
    assert ns == expected
    assert element.get("xmlns") == "default ns"
    assert element.get("xmlns:junk-ns0") == "junk-ns value 0"
    assert element.get("xmlns:junk-ns1") == "junk-ns value 1"
    assert element.get("py:pyattr") == "py value"
    assert element.get("attr") == "a new attr"

    ns = namespaces(element, remove=True)
    assert element.get("xmlns") is None
    assert element.get("xmlns:junk-ns0") is None
    assert element.get("xmlns:junk-ns1") is None
    assert element.get("py:pyattr") == "py value"
    assert element.get("attr") == "a new attr"
 def attrib_proc(self, item, attrib, code):
     line = code.line
     need_interpolation = False
     names = namespaces(item, remove=True)
     for k, v in attrib.items():
         sub = interpolate(v)
         if id(sub) != id(v):
             attrib[k] = sub
             if isinstance(sub, list):
                 need_interpolation = True
     expr = attrib.get(QNAME_ATTRIBUTES)
     if expr is not None:
         del attrib[QNAME_ATTRIBUTES]
         attr_text = ('template_util.make_updated_attrib('
             '%r, "%s", globals(), locals(), self._get_assume_encoding())'
             % (attrib, expr.replace('"', '\\\"')))
     else:
         if attrib:
             if need_interpolation:
                 attr_text = ('template_util.make_attrib('
                     '%r, self._get_assume_encoding())' % attrib)
             else:
                 attr_text = repr(attrib)
         else:
             attr_text = '{}'
     line('ancestors.insert(0, current)',
         'current = Element(%r, %s)' % (item.tag, attr_text))
     if len(names):
         code.start_block('for _p, _u in %r.items():' % names)
         line('if not _u in omit_namespaces: yield START_NS, (_p,_u)')
         code.end_block()
     line('yield START, current')
Ejemplo n.º 3
0
    def generate(self, stream, encoding=None, fragment=False, format=None):
        """Serializes an event stream to bytes of the specified encoding.

        This function yields an encoded string over and over until the
        stream is exhausted.

        """
        doctype = self.doctype
        encoding = encoding or self.encoding or 'utf-8'
        entity_map = self.entity_map
        transpose = self.transpose
        inject_type = self.inject_type
        format = self._get_format(format)
        if format:
            if format.doctype is not None:
                doctype = format.doctype
            if format.entity_map is not None:
                entity_map = format.entity_map
            if format.transpose is not None:
                transpose = format.transpose
            if format.inject_type is not None:
                inject_type = format.inject_type
        if entity_map == True:
            # if True, use default HTML entity map
            entity_map = default_entity_map
        elif entity_map == False:
            entity_map = None
        if isinstance(doctype, basestring):
            # allow doctype strings
            doctype = doctypes[self.doctype]
        if transpose is not None:
            if not callable(transpose):
                if transpose:
                    transpose = lambda s: s.upper()
                else:
                    transpose = lambda s: s.lower()

        escape_cdata = HTMLSerializer.escape_cdata
        escape_attrib = HTMLSerializer.escape_attrib
        names = NamespaceStack(self.namespaces)

        def grok_name(tag):
            if tag[0] == '{':
                uri, localname = tag[1:].split('}', 1)
            else:
                uri, localname = None, tag
            if uri and uri != xhtml_uri:
                qname = names.qname(tag, default=False)
            else:
                qname = localname
                if transpose:
                    qname = transpose(qname)
            return uri, localname, qname

        current = None
        stack = [current]
        stream = iter(stream)

        if not fragment and doctype is not None:
            yield serialize_doctype(doctype) + '\n'

        if inject_type and encoding:
            stream = self.inject_meta_content_type(stream, encoding)

        for ev, item in self.apply_filters(stream, format):
            if ev == TEXT and item:
                escape = self.is_escape(current)
                yield escape_cdata(item, encoding, entity_map, escape)
            elif ev == START:
                if item.tag == Comment:
                    yield "<!--%s-->" % item.text.encode(encoding)
                    continue
                elif item.tag == ProcessingInstruction:
                    yield "<?%s>" % item.text.encode(encoding)
                    continue
                elif item.tag == Fragment:
                    continue
                else:
                    names.push(namespaces(item, remove=True))
                    tag = item.tag
                    qname = grok_name(tag)[2]
                    # push this name on the stack so we know where we are
                    current = qname.lower()
                    stack.append(current)
                    yield "<" + qname.encode(encoding)
                    attrs = item.attrib.items()
                    if attrs:
                        for k, v in attrs:
                            q = grok_name(k)[2]
                            lq = q.lower()
                            if lq == 'xml:lang':
                                continue
                            if self.is_boolean_attribute(lq):
                                # XXX: what if v is 0, false, or no.
                                #      should we omit the attribute?
                                yield ' %s' % q.encode(encoding)
                            else:
                                yield ' %s="%s"' % (
                                    q.encode(encoding),
                                    escape_attrib(v, encoding, entity_map))
                    yield ">"
            elif ev == END and item.tag not in (Comment, ProcessingInstruction,
                                                Fragment):
                current = stack.pop()
                if not self.can_be_empty_element(current):
                    tag = item.tag
                    qname = grok_name(tag)[2]
                    yield "</%s>" % qname.encode(encoding)
                current = stack[-1]
                names.pop()
Ejemplo n.º 4
0
    def generate(self, stream, encoding=None, fragment=False, format=None):
        """Serializes an event stream to bytes of the specified encoding.

        This function yields an encoded string over and over until the
        stream is exhausted.

        """
        decl = self.decl
        doctype = self.doctype
        encoding = encoding or self.encoding or 'utf-8'
        entity_map = self.entity_map
        format = self._get_format(format)
        if format:
            if format.decl is not None:
                decl = format.decl
            if format.doctype is not None:
                doctype = format.doctype
            if format.entity_map is not None:
                entity_map = format.entity_map
        if entity_map == True:
            # if True, use default HTML entity map
            entity_map = default_entity_map
        elif entity_map == False:
            entity_map = None
        if isinstance(doctype, basestring):
            # allow doctype strings
            doctype = doctypes[self.doctype]

        escape_cdata = XMLSerializer.escape_cdata
        escape_attrib = XMLSerializer.escape_attrib

        lastev = None
        stream = iter(stream)
        names = NamespaceStack(self.namespaces)
        if not fragment:
            if decl:
                yield '<?xml version="1.0" encoding="%s"?>\n' % encoding
            if doctype is not None:
                yield serialize_doctype(doctype) + '\n'
        text = None
        for ev, item in self.apply_filters(stream, format):
            if ev in (START, END) and item.tag == Fragment:
                continue
            elif ev == TEXT:
                if text is not None:
                    text = u''.join([text, item])
                else:
                    text = item
                continue
            if lastev == START:
                if ev == END and (not text or not (Format.strip(text)
                        or self.is_formatted(item.tag))) \
                        and self.can_be_empty_element(item.tag):
                    yield ' />'
                    lastev = END
                    text = None
                    names.pop()
                    continue
                yield ">"
            if text:
                yield escape_cdata(text, encoding, entity_map)
                text = None
            if ev == START:
                if item.tag == Comment:
                    yield "<!--%s-->" % item.text.encode(encoding)
                    lastev = COMMENT
                    continue
                elif item.tag == ProcessingInstruction:
                    yield "<?%s?>" % item.text.encode(encoding)
                    lastev = PI
                    continue
                else:
                    current_names = names.current
                    names.push(namespaces(item, remove=True))
                    qname = names.qname(item.tag, default=True)
                    yield "<" + qname.encode(encoding)
                    for k, v in item.attrib.items():
                        k = names.qname(k, default=False).encode(encoding)
                        v = escape_attrib(v, encoding)
                        yield ' %s="%s"' % (k, v)
                    for prefix, uri in names.current.items():
                        if prefix not in current_names \
                                or current_names[prefix] != uri:
                            v = escape_attrib(uri, encoding)
                            if prefix:
                                k = 'xmlns:' + prefix.encode(encoding)
                            else:
                                k = 'xmlns'
                            yield ' %s="%s"' % (k, v)
            elif ev == END and item.tag not in (Comment,
                                                ProcessingInstruction):
                qname = names.qname(item.tag, default=True)
                yield "</%s>" % qname.encode(encoding)
                names.pop()
            lastev = ev
        if fragment and text:
            yield escape_cdata(text, encoding, entity_map)
        return
Ejemplo n.º 5
0
    def generate(self, stream, encoding=None,
            fragment=False, format=None):
        """Serializes an event stream to bytes of the specified encoding.

        This function yields an encoded string over and over until the
        stream is exhausted.

        """
        doctype = self.doctype
        encoding = encoding or self.encoding or 'utf-8'
        entity_map = self.entity_map
        transpose = self.transpose
        inject_type = self.inject_type
        format = self._get_format(format)
        if format:
            if format.doctype is not None:
                doctype = format.doctype
            if format.entity_map is not None:
                entity_map = format.entity_map
            if format.transpose is not None:
                transpose = format.transpose
            if format.inject_type is not None:
                inject_type = format.inject_type
        if entity_map == True:
            # if True, use default HTML entity map
            entity_map = default_entity_map
        elif entity_map == False:
            entity_map = None
        if isinstance(doctype, basestring):
            # allow doctype strings
            doctype = doctypes[self.doctype]
        if transpose is not None:
            if not callable(transpose):
                if transpose:
                    transpose = lambda s: s.upper()
                else:
                    transpose = lambda s: s.lower()

        escape_cdata = HTMLSerializer.escape_cdata
        escape_attrib = HTMLSerializer.escape_attrib
        names = NamespaceStack(self.namespaces)

        def grok_name(tag):
            if tag[0] == '{':
                uri, localname = tag[1:].split('}', 1)
            else:
                uri, localname = None, tag
            if uri and uri != xhtml_uri:
                qname = names.qname(tag, default=False)
            else:
                qname = localname
                if transpose:
                    qname = transpose(qname)
            return uri, localname, qname

        current = None
        stack = [current]
        stream = iter(stream)

        if not fragment and doctype is not None:
            yield serialize_doctype(doctype) + '\n'

        if inject_type and encoding:
            stream = self.inject_meta_content_type(stream, encoding)

        for ev, item in self.apply_filters(stream, format):
            if ev == TEXT and item:
                escape = self.is_escape(current)
                yield escape_cdata(item, encoding, entity_map, escape)
            elif ev == START:
                if item.tag == Comment:
                    yield "<!--%s-->" % item.text.encode(encoding)
                    continue
                elif item.tag == ProcessingInstruction:
                    yield "<?%s>" % item.text.encode(encoding)
                    continue
                elif item.tag == Fragment:
                    continue
                else:
                    names.push(namespaces(item, remove=True))
                    tag = item.tag
                    qname = grok_name(tag)[2]
                    # push this name on the stack so we know where we are
                    current = qname.lower()
                    stack.append(current)
                    yield "<" + qname.encode(encoding)
                    attrs = item.attrib.items()
                    if attrs:
                        for k, v in attrs:
                            q = grok_name(k)[2]
                            lq = q.lower()
                            if lq == 'xml:lang':
                                continue
                            if self.is_boolean_attribute(lq):
                                # XXX: what if v is 0, false, or no.
                                #      should we omit the attribute?
                                yield ' %s' % q.encode(encoding)
                            else:
                                yield ' %s="%s"' % (
                                    q.encode(encoding),
                                    escape_attrib(v, encoding, entity_map))
                    yield ">"
            elif ev == END and item.tag not in (
                    Comment, ProcessingInstruction, Fragment):
                current = stack.pop()
                if not self.can_be_empty_element(current):
                    tag = item.tag
                    qname = grok_name(tag)[2]
                    yield "</%s>" % qname.encode(encoding)
                current = stack[-1]
                names.pop()
Ejemplo n.º 6
0
    def generate(self, stream, encoding=None,
            fragment=False, format=None):
        """Serializes an event stream to bytes of the specified encoding.

        This function yields an encoded string over and over until the
        stream is exhausted.

        """
        decl = self.decl
        doctype = self.doctype
        encoding = encoding or self.encoding or 'utf-8'
        entity_map = self.entity_map
        format = self._get_format(format)
        if format:
            if format.decl is not None:
                decl = format.decl
            if format.doctype is not None:
                doctype = format.doctype
            if format.entity_map is not None:
                entity_map = format.entity_map
        if entity_map == True:
            # if True, use default HTML entity map
            entity_map = default_entity_map
        elif entity_map == False:
            entity_map = None
        if isinstance(doctype, basestring):
            # allow doctype strings
            doctype = doctypes[self.doctype]

        escape_cdata = XMLSerializer.escape_cdata
        escape_attrib = XMLSerializer.escape_attrib

        lastev = None
        stream = iter(stream)
        names = NamespaceStack(self.namespaces)
        if not fragment:
            if decl:
                yield '<?xml version="1.0" encoding="%s"?>\n' % encoding
            if doctype is not None:
                yield serialize_doctype(doctype) + '\n'
        text = None
        for ev, item in self.apply_filters(stream, format):
            if ev in (START, END) and item.tag == Fragment:
                continue
            elif ev == TEXT:
                if text is not None:
                    text = u''.join([text, item])
                else:
                    text = item
                continue
            if lastev == START:
                if ev == END and (not text or not (Format.strip(text)
                        or self.is_formatted(item.tag))) \
                        and self.can_be_empty_element(item.tag):
                    yield ' />'
                    lastev = END
                    text = None
                    names.pop()
                    continue
                yield ">"
            if text:
                yield escape_cdata(text, encoding, entity_map)
                text = None
            if ev == START:
                if item.tag == Comment:
                    yield "<!--%s-->" % item.text.encode(encoding)
                    lastev = COMMENT
                    continue
                elif item.tag == ProcessingInstruction:
                    yield "<?%s?>" % item.text.encode(encoding)
                    lastev = PI
                    continue
                else:
                    current_names = names.current
                    names.push(namespaces(item, remove=True))
                    qname = names.qname(item.tag, default=True)
                    yield "<" + qname.encode(encoding)
                    for k, v in item.attrib.items():
                        k = names.qname(k, default=False).encode(encoding)
                        v = escape_attrib(v, encoding)
                        yield ' %s="%s"' % (k, v)
                    for prefix, uri in names.current.items():
                        if prefix not in current_names \
                                or current_names[prefix] != uri:
                            v = escape_attrib(uri, encoding)
                            if prefix:
                                k = 'xmlns:' + prefix.encode(encoding)
                            else:
                                k = 'xmlns'
                            yield ' %s="%s"' % (k, v)
            elif ev == END and item.tag not in (
                    Comment, ProcessingInstruction):
                qname = names.qname(item.tag, default=True)
                yield "</%s>" % qname.encode(encoding)
                names.pop()
            lastev = ev
        if fragment and text:
            yield escape_cdata(text, encoding, entity_map)
        return