XML解析到一个哈希表

问题描述:

我有以下格式的XML文件:XML解析到一个哈希表

<doc> 
<id name="X"> 
    <type name="A"> 
    <min val="100" id="80"/> 
    <max val="200" id="90"/> 
    </type> 
    <type name="B"> 
    <min val="100" id="20"/> 
    <max val="20" id="90"/> 
    </type> 
</id> 

<type...> 
</type> 
</doc> 

我想解析这个文件,并建立一个哈希表

{X: {"A": [(100,80), (200,90)], "B": [(100,20), (20,90)]}, Y: .....} 

如何我会用Python做这个吗?

+0

这种问题已被问了几次。答案可能能够帮助你。 http://*.com/questions/191536/converting-xml-to-json-using-python http://*.com/questions/471946/how-to-convert-xml-to-json- in-python – Thomas 2009-12-15 16:04:09

正如其他人所指出minidom是去这里的路。您打开(并解析)文件,同时检查节点,检查节点是否与其相关并应读取。这样,你也知道你是否想读取子节点。

扔在一起这似乎做你想做的。有些值是通过属性位置而不是属性名称读取的。而且没有错误处理。最后的print()意味着它的Python 3.x.

我会把它作为一个练习来改进,只是想发布一个片段,让你开始。

快乐黑客! :)

xml.txt

<doc> 
<id name="X"> 
    <type name="A"> 
    <min val="100" id="80"/> 
    <max val="200" id="90"/> 
    </type> 
    <type name="B"> 
    <min val="100" id="20"/> 
    <max val="20" id="90"/> 
    </type> 
</id> 
</doc> 

parsexml.py

from xml.dom import minidom 
data={} 
doc=minidom.parse("xml.txt") 
for n in doc.childNodes[0].childNodes: 
    if n.localName=="id": 
     id_name = n.attributes.item(0).nodeValue 
     data[id_name] = {} 
     for j in n.childNodes: 
      if j.localName=="type": 
       type_name = j.attributes.item(0).nodeValue 
       data[id_name][type_name] = [(),()] 
       for k in j.childNodes: 
        if k.localName=="min": 
         data[id_name][type_name][0] = \ 
          (k.attributes.item(1).nodeValue, \ 
          k.attributes.item(0).nodeValue) 
        if k.localName=="max": 
         data[id_name][type_name][1] = \ 
          (k.attributes.item(1).nodeValue, \ 
          k.attributes.item(0).nodeValue) 
print (data) 

输出:

{'X': {'A': [('100', '80'), ('200', '90')], 'B': [('100', '20'), ('20', '90')]}} 
+3

对不起,错了房间。富尔代码竞赛在大厅里。 – 2009-12-15 21:31:51

我建议使用minidom库。

文档非常好,所以你应该立即开始运行。

丹。

为什么不尝试类似PyXml库。他们有很多文档和教程。

+3

**警告**挪威蓝鹦鹉综合征:5年前的最新版本。没有用于Python 2.5和2.6的Windows安装程序。 – 2009-12-16 21:27:20

+0

我对BeautifulSoup和解析URL比本地XML文件更熟悉,所以这对我来说是一个很好的解决方案。 – Flowpoke 2011-03-08 23:47:21

我同不同意sugges在其他使用minidom的答案中 - 这是一种Python的改编,最初是为其他语言设计的标准,适用于但不是很适合。现代Python中推荐的方法是ElementTree

在第三方模块lxml中也实现了相同的接口,但除非您需要超速,Python标准库中包含的版本没有问题(并且速度也比minidom快) - 关键是编程到那个接口,那么如果你愿意,你可以在将来随时切换到相同接口的不同实现,只需对自己的代码进行最小限度的更改。

例如,在需要导入& c后,下面的代码是您的示例的最小实现(它不验证XML是否正确,只是假设正确提取数据 - 添加各种检查很漂亮当然容易):

from xml.etree import ElementTree as et # or, import any other, faster version of ET 

def xml2data(xmlfile): 
    tree = et.parse(xmlfile) 
    data = {} 
    for anid in tree.getroot().getchildren(): 
    currdict = data[anid.get('name')] = {} 
    for atype in anid.getchildren(): 
     currlist = currdict[atype.get('name')] = [] 
     for c in atype.getchildren(): 
     currlist.append((c.get('val'), c.get('id'))) 
    return data 

这给你的样品输入产生你想要的结果。

+0

'对于node.getchildren()中的孩子'':不必要;改为在节点中使用'child:'。 – 2009-12-16 21:27:59

+0

*警告*:对于恶意构造的数据,xml.etree.ElementTree模块不安全。如果您需要解析不可信或未经身份验证的数据,请参阅XML漏洞。只是要小心。 – igaurav 2015-01-27 05:39:56

不要重新发明*。使用Amara工具包。 无论如何,变量名称只是字典中的键。 http://www.xml3k.org/Amara

+0

另一个链接 - http://www.xml.com/pub/a/2005/01/19/amara.html 你将最终得到一个变量doc,它有doc.id,它有doc.id.type [0],然后是doc.id.type [0] .min,...等等。超容易访问! – 2009-12-15 21:33:02