xml - 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 文件本身?
解决方案
您可以从解析的 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 字典,那么迭代并找到您想要的内容将非常简单。
推荐阅读
- .net - 流式传输 9 MB 文件时发生 System.IO.DirectoryNotFoundException - .NET Core 2.2(使用 Kestrel)
- datasource - 在 Google 应用制作工具中查找模型的大小
- python - 将 MP3 转换为 WAV 时出现 2 个错误
- laravel - Laravel:发布对象数组
- node.js - nodemon安装问题作为开发模式
- spring - Spring ConstraintViolation 未捕获
- sql - 基于表数据动态形成的SQL查询
- node.js - 为什么我在尝试连接猫鼬时收到“mongoose.connect 不是函数”?
- pytorch - 如何在不使用 python 索引的情况下切片火炬张量
- gstreamer - 我如何将文件位置设置为 gst-launch 命令行?