Python:解析用dicts构建的xml文件

2024-04-16 07:27:58 发布

您现在位置:Python中文网/ 问答频道 /正文

[Python 3.4][Windows 7]

如果有任何简单的方法可以将整个.xml文件(如.txt)作为一个字符串,这就足够了,但要准确地描述问题:

这是我第一次处理.xml文件。 我有一个.xml文件,主要包含字典(更多的字典)。 它还说 现在,我想从字典中获取非常确定的键和值,并将它们写入一个.txt文件中,因此用python编写dict(或其他东西)就足够了。在

举个例子:

这是xml文件(库.xml)公司名称:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>Version<\key><integer>1</integer>
    <key>Tracks</key>
    <dict>
        <key>0001</key>
        <dict>
            <key>Name</key><string>spam</string>
            <key>Detail</key><string>spam spam</string>
        </dict>
        <key>0002</key>
        <dict>
            <key>Name</key><string>ham</string>
            <key>Detail</key><string>ham ham</string>
        </dict>
    </dict>
</dict>
</plist>

我研究过,认为我可以用xml.etree.ElementTree模块: 所以如果我试试这个:

^{pr2}$

我只收到这样的信息:

(Unicode错误)“UnicodeScape”编解码器无法解码字节

我想要的显然是这样(或者说,这无关紧要)

[['Name: spam', 'Detail: spam spam'], ['Name: ham', 'Detail: ham ham']

编辑:xml代码不正确,sry 编辑:添加最后一段


Tags: 文件keynametxt编辑string字典version
3条回答

Python标准库包含一个读取plist文件的模块:^{}。您可以使用它通过导入和一个命令来解决问题:

import plistlib

print plistlib.readPlist('library.xml')

输出:

^{pr2}$

将输入内容从<\key>更新为</key>,并删除了dict标记,因为没有为此定义键。在

  1. 通过lxml.html模块解析XML数据。在
  2. 通过xpath()方法获取目标maindict标记。在
  3. 调用XMLtoDict()函数。在
  4. 通过getchildren()方法和for循环迭代输入标记的子级。在
  5. 通过if循环检查标记名是否为键。在
  6. 如果是,则通过getnext()方法获取当前标记的下一个标记。在
  7. 如果下一个标记是integer标记,则获取值类型int。在
  8. 如果下一个标记是string标记,那么值类型是string。在
  9. 如果下一个标记是dict标记,那么值类型是dict,并再次调用函数,即递归调用。在
  10. 将键和值添加到结果字典中。在
  11. 返回结果字典。在
  12. 打印结果字典。在

代码:

data = """<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
    <dict>
        <key>Version</key>
        <integer>1</integer>
        <key>Tracks</key>
        <dict>
            <key>0001</key>
            <dict>
                <key>Name</key><string>spam</string>
                <key>Detail</key><string>spam spam</string>
            </dict>
            <key>0002</key>
            <dict>
                <key>Name</key><string>ham</string>
                <key>Detail</key><string>ham ham</string>
            </dict>
        </dict>
    </dict>
</plist>
"""

def XMLtoDict(root):
    result = {}
    for i in root.getchildren():
        if i.tag=="key":
            key = i.text
            next_tag = i.getnext()
            next_tag_name = next_tag.tag
            if next_tag_name=="integer":
                value = int(next_tag.text)
            elif next_tag_name=='string':
                value = next_tag.text
            elif next_tag_name=='dict':
                value = XMLtoDict(next_tag)
            else:
                value = None
            result[key] = value

    return dict(result)


import lxml.html as ET
import pprint

root = ET.fromstring(data)
result = XMLtoDict(root.xpath("//plist/dict")[0])
pprint.pprint(result)

输出:

^{pr2}$
  1. 我没有得到这样的例外。在

    (Unicode错误)“UnicodeScape”编解码器无法解码字节…

  2. 标签在中不正确库.xml在

    进口xml.etree.ElementTree作为ET 树=ET.解析('库.xml')

获取以下输入异常

vivek@vivek:~/Desktop/stackoverflow$ python 12.py 
Traceback (most recent call last):
  File "12.py", line 46, in <module>
    tree = ET.parse('library.xml')
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1183, in parse
    tree.parse(source, parser)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 656, in parse
    parser.feed(data)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1643, in feed
    self._raiseerror(v)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1507, in _raiseerror
    raise err
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 4, column 15

此异常是由无效标记引起的。要修复此异常,请执行以下操作:

<key>Version<\key>更改为<key>Version</key>

  1. 通过xml.etree.ElementTree模块:

代码:

def XMLtoDict(root):
    result = {}
    chidren_tags = root.getchildren()
    for j, i in enumerate(chidren_tags):
        if i.tag=="key":
            key = i.text
            next_tag = chidren_tags[j+1]
            next_tag_name = next_tag.tag
            if next_tag_name=="integer":
                value = int(next_tag.text)
            elif next_tag_name=='string':
                value = next_tag.text
            elif next_tag_name=='dict':
                value = XMLtoDict(next_tag)
            else:
                value = None
            result[key] = value

    return dict(result)


def XMLtoList(root):
    result = []
    chidren_tags = root.getchildren()
    for j, i in enumerate(chidren_tags):
        if i.tag=="key":
            key = i.text
            next_tag = chidren_tags[j+1]
            next_tag_name = next_tag.tag
            if next_tag_name=="integer":
                value = int(next_tag.text)
            elif next_tag_name=='string':
                value = next_tag.text
            elif next_tag_name=='dict':
                value = XMLtoList(next_tag)
            else:
                value = None
            result.append([key, value])

    return list(result)


import xml.etree.ElementTree as ET
import pprint

tree = ET.parse('library.xml')
root = tree.getroot()

dict_tag = root.find("dict")
if dict_tag is not None:
    result = XMLtoDict(dict_tag)
    print "Result in Dictinary:-"
    pprint.pprint(result)

    result = XMLtoList(dict_tag)
    print "\nResult in Dictinary:-"
    pprint.pprint(result)

输出: vivek@vivek公司:~/Desktop/stackoverflow$python 12.py

Result in Dictinary:-
{'Tracks': {'0001': {'Detail': 'spam spam', 'Name': 'spam'},
            '0002': {'Detail': 'ham ham', 'Name': 'ham'}},
 'Version': 1}

Result in Dictinary:-
[['Version', 1],
 ['Tracks',
  [['0001', [['Name', 'spam'], ['Detail', 'spam spam']]],
   ['0002', [['Name', 'ham'], ['Detail', 'ham ham']]]]]]

我只想让你知道我已经解决了这个问题:

with open('library.xml',
          'r', encoding='UTF-8') as file:

(和一些正则表达式来获得我想要的dicts)

这可能是非常低效的,因为我将完整的文件作为文本读取,但实际上我不关心效率,因为函数在我的程序中只有一个调用;)

相关问题 更多 >