encoding during elementtree serialization

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris McDonough

    #1

    encoding during elementtree serialization

    ElementTree's XML serialization routine implied by tree._write(fil e,
    node, encoding, namespaces looks like this (elided):

    def _write(self, file, node, encoding, namespaces):
    # write XML to file
    tag = node.tag
    if tag is Comment:
    file.write("<!-- %s -->" % _escape_cdata(n ode.text, encoding))
    elif tag is ProcessingInstr uction:
    file.write("<?% s?>" % _escape_cdata(n ode.text, encoding))
    else:
    ....
    file.write("<" + _encode(tag, encoding))
    if items or xmlns_items:
    items.sort() # lexical order

    Note that "_escape_cd ata" (which also performs encoding) and "_encode"
    are called for pcdata (and attribute values) only, but not for the tag
    literals like "<" and "<?%s?>".

    In some profiling I've done, I believe encoding during recursion makes
    serialization slightly slower than it could be if we could get away with
    not encoding any pcdata or attribute values during recursion.

    Instead, we might be able to get away with encoding everything just once
    at the end. But I don't know if this is kosher. Is there any reason to
    not also encode tag literals and quotation marks that are attribute
    containers, just once, at the end of serialization?

    Even if that's not acceptable in general because tag literals cannot be
    encoded, would it be acceptable for "ascii-compatible" encodings like
    utf-8, latin-1, and friends?

    Something like:

    def _escape_cdata(t ext, encoding=None, replace=string. replace):
    # doesn't do any encoding
    text = replace(text, "&", "&amp;")
    text = replace(text, "<", "&lt;")
    text = replace(text, ">", "&gt;")
    return text

    class _ElementInterfa ce:

    ...

    def write(self, file, encoding="us-ascii"):
    assert self._root is not None
    if not hasattr(file, "write"):
    file = open(file, "wb")
    if not encoding:
    encoding = "us-ascii"
    elif encoding != "utf-8" and encoding != "us-ascii":
    file.write("<?x ml version='1.0' encoding='%s'?> \n" % encoding)
    tmp = StringIO()
    self._write(tmp , self._root, encoding, {})
    file.write(tmp. getvalue().enco de(encoding))


    def _write(self, file, node, encoding, namespaces):
    # write XML to file
    tag = node.tag
    if tag is Comment:
    file.write("<!-- %s -->" % _escape_cdata(n ode.text, encoding))
    elif tag is ProcessingInstr uction:
    file.write("<?% s?>" % _escape_cdata(n ode.text, encoding))
    else:
    items = node.items()
    xmlns_items = [] # new namespaces in this scope
    try:
    if isinstance(tag, QName) or tag[:1] == "{":
    tag, xmlns = fixtag(tag, namespaces)
    if xmlns: xmlns_items.app end(xmlns)
    except TypeError:
    _raise_serializ ation_error(tag )
    file.write("<" + tag)


    I smell the mention of a Byte Order Mark coming on. ;-)
Working...