草庐IT

python - XML 到/从 Python 字典

coder 2024-06-26 原文

我需要使用 Python 2.4.4 将 XML 与 Python 字典相互转换。我只需要节点名称和值,我不担心属性,因为我正在解析的 XML 没有任何属性。我不能使用 ElementTree,因为它不适用于 2.4.4,而且由于我的工作环境,我不能使用第 3 方库。对我来说最简单的方法是什么?有什么好的片段吗?

此外,如果没有简单的方法来执行此操作,是否有 Python 2.4.4 原生支持的其他序列化格式?

最佳答案

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

我还包含了一些特定于我正在编写的应用程序的快捷方式(在文档字符串中进行了解释),但您可能会发现这些快捷方式也很有用,从它的声音来看。本质上,一个 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

关于python - XML 到/从 Python 字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3292973/

有关python - XML 到/从 Python 字典的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  8. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

  9. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  10. Python 刷Leetcode题库,顺带学英语单词(31) - 2

    ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

随机推荐