首页 > 解决方案 > XML 文件的结构阻止我用 python 读取它

问题描述

我正在设置一个 python 脚本,它将询问所有具有相同格式的输入 xml 文件的列表,并从每个 xml 文件中读出特定的行。

一切都按我的意愿工作,但是由于 xml 文件本身的内容,从 xml 文件读取时出现错误。

我已经通过编辑 xml 文件让脚本工作,但这对我来说不是一个解决方案,因为我需要这个脚本来运行数千个文件

这是我正在使用的代码:

import os
import tkinter as tk
from tkinter import filedialog
import xml.etree.ElementTree as ET


root = tk.Tk()
root.withdraw()

file_path = filedialog.askopenfilenames()

tup=0

count = len(file_path)

for i in range(len(file_path)):
    filename = os.path.basename(file_path[tup])
    print('file =',os.path.basename(' '.join(file_path)))
    tree = ET.parse(file_path[tup])
    root = tree.getroot()
    for child in root:
        data = child.tag
        print(data)
    for data in root.findall(data):
        name = data.find('subdata2').text
        print('ID =', name)
    tup +=1

这是xml的一个例子:

<?xml version="1.0"?>
<Data xmlns="link">
    <subdata1 id = "something">
        <subdata2>data
            <subdata3>data</subdata3>
        </subdata2>
    </subdata1>
</Data>

问题来自附加到根“link3”的文本,它将 subdata1 的标签从

subdata1

 {link}subdata1

然后将输出更改为:

ID = data

至:

Traceback (most recent call last):
  File "debug.py", line 25, in <module>
    name = data.find('subdata2').text
AttributeError: 'NoneType' object has no attribute 'text'

是否有另一种方法可以从此 xml 文件中提取数据,而不涉及修改 xml 文件本身?

标签: xmlpython-3.xtkintertk

解决方案


您可以从解析的 xml 而不是 xml 本身中剥离名称空间。

tree = ET.iterparse(file_path)
for _, el in tree:
    if '}' in el.tag:
        el.tag = el.tag.split('}', 1)[1]  # strip all namespaces
root = tree.root
for child in root:
    # ... (REST OF CODE)

在这里阅读更多


此外,如果您不介意速度不够但想要极致简单,则可以使用 untangle。由于您的 XML 的结构显然都相同,这对您来说可能很方便。

import untangle

root = untangle.parse(file_path)
print(root.Data.subdata1['id'])
print(root.Data.subdata1.subdata2.cdata)

我也忘记了我最喜欢的选择。xmltodict 将 xml 转换为 Python OrderedDict 对象。

import xmltodict

with open(xmlPath, 'rb') as fd:
    xmlDict = xmltodict.parse(fd)
print(xmlDict['Data']['subdata1']['@id'])
print(xmlDict['Data']['subdata1']['subdata2']['#text'])

如您所见,命名空间不会成为问题。如果您熟悉 Python 字典,那么迭代并找到您想要的内容将非常简单。


推荐阅读