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')
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()
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
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()
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