【问题标题】:Add attribute to an Element of xml.etree.ElementTree and make serializable to XML将属性添加到 xml.etree.ElementTree 的元素并使其可序列化为 XML
【发布时间】:2016-02-08 20:32:40
【问题描述】:

我想从xml.etree.ElementTree 向Element 的某个实例添加一个属性,以便将numpy.ndarray 等卫星数据存储到某些树的节点中。这可能吗,因为该对象没有公开__dict__ 和__slot__?

我知道我可以使用get/set方法来填充节点属性,但是如果它包含str以外的其他对象,则无法序列化为XML。

Traceback (most recent call last):
  File "latexer.py", line 576, in <module>
    main(sys.argv)
  File "latexer.py", line 565, in main
    r.dump(**k)
  File "latexer.py", line 406, in dump
    code = self.__fileFormats[ufformat]()
  File "latexer.py", line 416, in getXML
    rawstr = ET.tostring(self._document, encoding='utf-8', method='xml')
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 1171, in tostring
    ElementTree(element).write(stream, encoding, method=method)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 828, in write
    serialize(write, self._root, qnames, namespaces)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 990, in _serialize_xml
    _serialize_xml(write, e, qnames, None)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 990, in _serialize_xml
    _serialize_xml(write, e, qnames, None)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 990, in _serialize_xml
    _serialize_xml(write, e, qnames, None)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 983, in _serialize_xml
    v = _escape_attrib(v)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 1139, in _escape_attrib
    _raise_serialization_error(text)
  File "C:\Python33\lib\xml\etree\ElementTree.py", line 1105, in _raise_serialization_error
    "cannot serialize %r (type %s)" % (text, type(text).__name__)
TypeError: cannot serialize 1 (type int)

有没有办法添加bool或integer等属性,然后将其序列化为XML?

【问题讨论】:

  • 你试过https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element属性attrib吗?
  • @AnthonyKong 谢谢你强调它,我想不知何故(也许是 XML 的阴暗面)它可能只是存储在这本字典中的文本。
  • @AnthonyKong 我已经编辑了我的问题,因为我仍然卡在某个点上。

标签: python dynamic attr


【解决方案1】:

在阅读了一些关于这个问题的其他帖子后,我接受了这个问题没有直接、优雅的解决方案,因为 - 有充分的理由 - nat 所有对象都可以隐式转换为字符串。

然后,我找到了一种中间方式。该技术包括腌制经过处理的物体。当我想访问它时,只需调用相反的过程。

我知道它在数据存储和计算开销方面效率不高,但它有效并解决了我的问题,因为我的树需要转储为 XML 并在之后重新打开。

代码如下:

def _fillNode(self, node, text=None, **kwargs):
    """Fill a given node with text and arguments (serialized if non string) from kwargs"""
    node.text = text
    for (k, v) in kwargs.items():
        # Append string as this:
        if isinstance(v, str):
            node.set(k, v)
        # If not a string pickle, hexlify and encode: 
        else:
            node.set(k, binascii.hexlify(pickle.dumps(v)).decode())
    return node

def _getAttribute(self, node, key, default=None):
    """Get node attribute as string but try first to deserialize it"""
    # Try to recover string formated data:
    value = node.get(key)
    if value:
        try:
            # try to decode, unhexlify and unpickle:
            return pickle.loads(binascii.unhexlify(value.encode()))
        except:
            # If not return as this
            return value
    else:
        return default

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-06
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多