提问人:x89 提问时间:1/23/2023 最后编辑:x89 更新时间:10/23/2023 访问量:173
在解析 XML 文件时,需要类似字节的对象,而不是“str”
a bytes-like object is required, not 'str' while parsing XML files
问:
我正在尝试解析如下所示的 xml。我想提取有关 katagorie 的信息,即 ID、父母 ID 等:
<?xml version="1.0" encoding="UTF-8"?>
<test timestamp="20210113">
<kategorien>
<kategorie id="1" parent_id="0">
Sprache
</kategorie>
</kategorien>
</test>
我正在尝试这个
fields = ['id', 'parent_id']
with open('output.csv', 'wb') as fp:
writer = csv.writer(fp)
writer.writerow(fields)
tree = ET.parse('./file.xml')
# from your example Locations is the root and Location is the first level
for elem in tree.getroot():
writer.writerow([(elem.get(name) or '').encode('utf-8')
for name in fields])
但是我收到此错误:
in <module>
writer.writerow(fields)
TypeError: a bytes-like object is required, not 'str'
即使我已经在我的代码中使用了。如何摆脱此错误?encode('utf-8')
答:
1赞
Sam
1/23/2023
#1
编辑 2如果要查找有关嵌套属性或子类的信息,有两种方法:
- 您可以使用嵌套循环:
for elem in root:
for child in elem:
print([(child.attrib.get(name) or 'c') for name in fields])
输出:
['1', '0']
在这里,它也可以返回具有 和 但没有 name 的类。id
parent_id
kategorie
- 如果要以更高的性能和更少的内存执行任务:
for elem in root.iter('kategorie'):
print([(elem.attrib.get(name) or 'c') for name in fields])
输出:
['1', '0']
对于此方法,它将返回名为 的每个类和子类。kategorie
编辑1:对于评论中的问题:
<?xml version="1.0"?>
<kategorien>
<kategorie id="1" parent_id="0">
Sprache
</kategorie>
</kategorien>
对于上面的文件,代码似乎运行良好:xml
fields = ['id', 'parent_id']
for elem in tree.getroot():
print([(elem.attrib.get(name) or 'c') for name in fields])
输出:
['1', '0']
原文答案:看起来您正在查看错误的位置。错误实际上发生在
writer.writerow(fields)
fields
是一个包含 和 not 的列表,这就是它给你错误的原因。我本来建议您将写入类型从更改为 ,但查看其余代码,看起来您想写入 .str
byte
wb
w
byte
writer.writerow([x.encode('utf-8') for x in fields])
encode()
只需将您的数据转换为表单。byte
评论
0赞
x89
1/23/2023
不,我不需要编码。我更改为“w”并使用了它,但它无法正确提取元素,因此,我的输出文件中只有“c”writer.writerow([(elem.get(name) or 'c') for name in fields])
0赞
Sam
1/23/2023
你的做法有点不正确。 将只是一个 或位置指针。假设您已设置为 file 的子项,您可以执行 .elem
iterable
name
attribute
xml
[(elem.attrib.get(name) or 'c') for name in fields]
0赞
Sam
1/23/2023
attrib
返回一个字典,其中包含{ <attribute> : <value>}
0赞
Sam
1/23/2023
你能提供一个最小的可重现文件的例子吗?xml
0赞
Sam
1/23/2023
另外,我建议您根据当前面临的问题编辑您的问题。
0赞
tdelaney
1/24/2023
#2
我看到两个问题。首先,您不需要自己进行编码。打开不带“b”二进制标志的文件并跳过 .encode。文件对象将为您进行编码。您看到的错误来自包含未编码字符串的列表。但是,如果您一开始就不以二进制形式打开,那就不是问题了。['id', 'parent_id']
其次,你迭代了错误的元素。在你的循环中添加一个,你会看到。相反,您可以与伪 xpath 一起使用来获取所需的元素。print(elem)
findall
import csv
import xml.etree.ElementTree as ET
fields = ['id', 'parent_id']
with open('output.csv', 'w') as fp:
writer = csv.writer(fp)
writer.writerow(fields)
tree = ET.parse('./file.xml')
# from your example Locations is the root and Location is the first level
for elem in tree.getroot().findall('kategorien/kategorie'):
writer.writerow([(elem.get(name) or '')
for name in fields])
评论
wb
for elem in tree.getroot()[0]
tree.getroot()
test
kategorien