XML 文件的结构阻止我使用 python 读取它

Structure of XML file is preventing me from reading it with 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 文件中提取数据?

您可以从解析的 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)

阅读更多here


此外,如果您不介意缺乏速度但想要极致简单,还有另一种选择,您可以使用 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 指令,那么迭代并找到您想要的内容将非常简单。