XML到/来自Python字典的XML

Lia*_*iam 4 python xml serialization xml-serialization python-2.4

我需要使用Python 2.4.4将XML转换为Python字典和从Python字典转换XML.我只需要节点名称和值,我不担心属性,因为我正在解析的XML没有任何属性.我无法使用,ElementTree因为2.4.4不可用,因为我的工作环境,我无法使用第三方库.对我来说最简单的方法是什么?有什么好的片段吗?

此外,如果没有一种简单的方法可以做到这一点,那么Python 2.4.4是否有本机支持的替代序列化格式?

Dou*_*g F 5

我最近编写了一些代码来将XML转换为python数据结构,尽管我必须处理属性.出于类似的原因,我使用xml.dom.minidom而不是ElementTree.我实际上没有在Python 2.4.4上测试过这个,但我认为它会起作用.我没有编写反向XML生成器,尽管您可以使用我包含的'lispy_string'函数来执行此操作.

我还包括了一些特定于我正在编写的应用程序的快捷方式(在docstring中解释),但是你可能会发现这些快捷方式也很有用.从本质上讲,xml树在技术上会转换为列表字典列表的字典列表等.我省略创建中间列表,除非它们是必要的,因此您可以通过dictname[element1][element2]而不是依次引用元素dictname[element1][0][element2][0].

属性处理有点笨拙,我强烈建议在使用属性做任何事情之前阅读代码.

import sys
from xml.dom import minidom

def dappend(dictionary, key, item):
    """Append item to dictionary at key.  Only create a list if there is more than one item for the given key.
    dictionary[key]=item if key doesn't exist.
    dictionary[key].append(item) if key exists."""
    if key in dictionary.keys():
        if not isinstance(dictionary[key], list):
            lst=[]
            lst.append(dictionary[key])
            lst.append(item)
            dictionary[key]=lst
        else:
            dictionary[key].append(item)
    else:
        dictionary.setdefault(key, item)

def node_attributes(node):
    """Return an attribute dictionary """
    if node.hasAttributes():
        return dict([(str(attr), str(node.attributes[attr].value)) for attr in node.attributes.keys()])
    else:
        return None

def attr_str(node):
    return "%s-attrs" % str(node.nodeName)

def hasAttributes(node):
    if node.nodeType == node.ELEMENT_NODE:
        if node.hasAttributes():
            return True
    return False

def with_attributes(node, values):
    if hasAttributes(node):
        if isinstance(values, dict):
            dappend(values, '#attributes', node_attributes(node))
            return { str(node.nodeName): values }
        elif isinstance(values, str):
            return { str(node.nodeName): values,
                     attr_str(node): node_attributes(node)}
    else:
        return { str(node.nodeName): values }

def xmldom2dict(node):
    """Given an xml dom node tree,
    return a python dictionary corresponding to the tree structure of the XML.
    This parser does not make lists unless they are needed.  For example:

    '<list><item>1</item><item>2</item></list>' becomes:
    { 'list' : { 'item' : ['1', '2'] } }
    BUT
    '<list><item>1</item></list>' would be:
    { 'list' : { 'item' : '1' } }

    This is a shortcut for a particular problem and probably not a good long-term design.
    """
    if not node.hasChildNodes():
        if node.nodeType == node.TEXT_NODE:
            if node.data.strip() != '':
                return str(node.data.strip())
            else:
                return None
        else:
            return with_attributes(node, None)
    else:
        #recursively create the list of child nodes
        childlist=[xmldom2dict(child) for child in node.childNodes if (xmldom2dict(child) != None and child.nodeType != child.COMMENT_NODE)]
        if len(childlist)==1:
            return with_attributes(node, childlist[0])
        else:
            #if False not in [isinstance(child, dict) for child in childlist]:
            new_dict={}
            for child in childlist:
                if isinstance(child, dict):
                    for k in child:
                        dappend(new_dict, k, child[k])
                elif isinstance(child, str):
                    dappend(new_dict, '#text', child)
                else:
                    print "ERROR"
            return with_attributes(node, new_dict)

def load(fname):
    return xmldom2dict(minidom.parse(fname))

def lispy_string(node, lst=None, level=0):
    if lst==None:
        lst=[]
    if not isinstance(node, dict) and not isinstance(node, list):
        lst.append(' "%s"' % node)
    elif isinstance(node, dict):
        for key in node.keys():
            lst.append("\n%s(%s" % (spaces(level), key))
            lispy_print(node[key], lst, level+2)
            lst.append(")")
    elif isinstance(node, list):
        lst.append(" [")
        for item in node:
            lispy_print(item, lst, level)
        lst.append("]")
    return lst

if __name__=='__main__':
    data = minidom.parse(sys.argv[1])

    d=xmldom2dict(data)

    print d
Run Code Online (Sandbox Code Playgroud)


小智 3

问题将 Python 字典序列化为 XML列出了 XML 序列化的一些方法。至于替代序列化格式,我认为picklemodule 是一个很好的工具。