将 XML 转换为 CSV 文件时获取空文件 Pandas Python
Getting empty file while converting XML to CSV file Pandas Python
这是我的 XML 文件
<Lieferantenbestellungen>
<Lieferantenbestellung>
<Jahr>2021</Jahr>
<Nummer>1</Nummer>
<Datum>2021-01-07</Datum>
<Lieferant_ID>459</Lieferant_ID>
<Positionen>
<Position Artikel="MCGPXO96" Bezeichnung="Refined Rubber Tuna" Menge="1" />
<Position Artikel="IYTAFI28" Bezeichnung="Generic Cotton Chicken" Menge="8" />
</Positionen>
</Lieferantenbestellung>
</Lieferantenbestellungen>
我想从文件中提取 Lieferant_ID、Artikel、Bezeichnung、Bezeichnung 和 Menge。
我有这个 python 代码:
with open('Lieferantenbestellungen.xml', 'r') as f:
soup = BeautifulSoup(f.read(), 'lxml')
# Get the data you want
df = pd.DataFrame(list(zip(
[el.text for el in soup.find_all('Lieferant_ID')],
[el.text for el in soup.find_all('Artikel')],
[el.text for el in soup.find_all('Bezeichnung')],
[el.text for el in soup.find_all('Menge')]
)), columns=['Lieferant_ID', 'Artikel', 'Bezeichnung', 'Menge'])
# Dump to csv
df.to_csv('out.csv', index=False)
当我 运行 代码生成 CSV 文件时,它是空的。有谁知道我做错了什么吗?
预期的 CSV 输出:
提前致谢
import xml.etree.ElementTree as ET
import csv
tree = ET.parse('your_file.xml')
root = tree.getroot()
returnitem = {}
for i in root.findall('Lieferantenbestellung'):
id = i.get('Lieferant_ID')
returnitem["Lieferant_ID"] = id
num = 0
for i2 in i.find("Positionen").findall("Position"):
Artikel = i2.find("Artikel").text
Bezeichnung = i2.find("Bezeichnung").text
Menge = i2.find("Menge").text
num += 1
returnitem["Data",str(num)] = {"Artikel":Artikel,"Bezeichnung":Bezeichnung,"Menge":Menge}
with open('result.csv', 'w') as f:
for key in returnitem.keys():
f.write("%s, %s\n" % (key, returnitem[key]))
这个程序应该可以解决你的问题
但是可能有一些 json/dictonary 形式的数据
pandas 现在有 .read_xml()
可以直接使用。
>>> pd.read_xml('Lieferantenbestellungen.xml', xpath='.//Lieferant_ID | .//Position')
Lieferant_ID Artikel Bezeichnung Menge
0 459.0 None None NaN
1 NaN MCGPXO96 Refined Rubber Tuna 1.0
2 NaN IYTAFI28 Generic Cotton Chicken 8.0
您可以 .ffill()
和 .dropna()
来“对齐”结果。
>>> df = pd.read_xml('Lieferantenbestellungen.xml', xpath='.//Lieferant_ID | .//Position')
>>> df['Lieferant_ID'] = df['Lieferant_ID'].ffill()
>>> df.dropna()
Lieferant_ID Artikel Bezeichnung Menge
1 459.0 MCGPXO96 Refined Rubber Tuna 1.0
2 459.0 IYTAFI28 Generic Cotton Chicken 8.0
要解析 xml,您需要执行 soup = BeautifulSoup(markup, "xml")
,而不是 "lxml"
。
执行此操作时,soup.find_all('Lieferant_ID')
returns ['459']
。
但是,多次执行 find_all()
并不是一个好主意,因为每个 Lieferantenbestellung
有多个 Positionen
标签。相反,我建议您 find_all("Lieferantenbestellung")
,然后处理每个标签。
此外,为了调试,将代码分成多行而不是将所有内容都塞到一行中会更容易。
with open('Lieferantenbestellungen.xml', 'r') as f:
soup = BeautifulSoup(f.read(), 'lxml')
rows = []
for tag in soup.find_all("Lieferantenbestellung")
lief_id = tag.findChild("Lieferant_ID")
if lief_id is None:
continue
for ptag in tag.findChild("Positionen").findChildren("Position"):
row = dict() # Make a new row
row["Lieferant_ID"] = lief_id.text
row["Artikel"] = ptag.attrs["Artikel"]
row["Bezeichnung"] = ptag.attrs["Bezeichnung"]
row["Menge"] = ptag.attrs["Menge"]
rows.append(row)
现在,您可以使用 pd.DataFrame.from_records()
创建数据框
pd.DataFrame.from_records(rows)
Lieferant_ID Artikel Bezeichnung Menge
0 459 MCGPXO96 Refined Rubber Tuna 1
1 459 IYTAFI28 Generic Cotton Chicken 8
这是我的 XML 文件
<Lieferantenbestellungen>
<Lieferantenbestellung>
<Jahr>2021</Jahr>
<Nummer>1</Nummer>
<Datum>2021-01-07</Datum>
<Lieferant_ID>459</Lieferant_ID>
<Positionen>
<Position Artikel="MCGPXO96" Bezeichnung="Refined Rubber Tuna" Menge="1" />
<Position Artikel="IYTAFI28" Bezeichnung="Generic Cotton Chicken" Menge="8" />
</Positionen>
</Lieferantenbestellung>
</Lieferantenbestellungen>
我想从文件中提取 Lieferant_ID、Artikel、Bezeichnung、Bezeichnung 和 Menge。
我有这个 python 代码:
with open('Lieferantenbestellungen.xml', 'r') as f:
soup = BeautifulSoup(f.read(), 'lxml')
# Get the data you want
df = pd.DataFrame(list(zip(
[el.text for el in soup.find_all('Lieferant_ID')],
[el.text for el in soup.find_all('Artikel')],
[el.text for el in soup.find_all('Bezeichnung')],
[el.text for el in soup.find_all('Menge')]
)), columns=['Lieferant_ID', 'Artikel', 'Bezeichnung', 'Menge'])
# Dump to csv
df.to_csv('out.csv', index=False)
当我 运行 代码生成 CSV 文件时,它是空的。有谁知道我做错了什么吗?
预期的 CSV 输出:
提前致谢
import xml.etree.ElementTree as ET
import csv
tree = ET.parse('your_file.xml')
root = tree.getroot()
returnitem = {}
for i in root.findall('Lieferantenbestellung'):
id = i.get('Lieferant_ID')
returnitem["Lieferant_ID"] = id
num = 0
for i2 in i.find("Positionen").findall("Position"):
Artikel = i2.find("Artikel").text
Bezeichnung = i2.find("Bezeichnung").text
Menge = i2.find("Menge").text
num += 1
returnitem["Data",str(num)] = {"Artikel":Artikel,"Bezeichnung":Bezeichnung,"Menge":Menge}
with open('result.csv', 'w') as f:
for key in returnitem.keys():
f.write("%s, %s\n" % (key, returnitem[key]))
这个程序应该可以解决你的问题 但是可能有一些 json/dictonary 形式的数据
pandas 现在有 .read_xml()
可以直接使用。
>>> pd.read_xml('Lieferantenbestellungen.xml', xpath='.//Lieferant_ID | .//Position')
Lieferant_ID Artikel Bezeichnung Menge
0 459.0 None None NaN
1 NaN MCGPXO96 Refined Rubber Tuna 1.0
2 NaN IYTAFI28 Generic Cotton Chicken 8.0
您可以 .ffill()
和 .dropna()
来“对齐”结果。
>>> df = pd.read_xml('Lieferantenbestellungen.xml', xpath='.//Lieferant_ID | .//Position')
>>> df['Lieferant_ID'] = df['Lieferant_ID'].ffill()
>>> df.dropna()
Lieferant_ID Artikel Bezeichnung Menge
1 459.0 MCGPXO96 Refined Rubber Tuna 1.0
2 459.0 IYTAFI28 Generic Cotton Chicken 8.0
要解析 xml,您需要执行 soup = BeautifulSoup(markup, "xml")
,而不是 "lxml"
。
执行此操作时,soup.find_all('Lieferant_ID')
returns ['459']
。
但是,多次执行 find_all()
并不是一个好主意,因为每个 Lieferantenbestellung
有多个 Positionen
标签。相反,我建议您 find_all("Lieferantenbestellung")
,然后处理每个标签。
此外,为了调试,将代码分成多行而不是将所有内容都塞到一行中会更容易。
with open('Lieferantenbestellungen.xml', 'r') as f:
soup = BeautifulSoup(f.read(), 'lxml')
rows = []
for tag in soup.find_all("Lieferantenbestellung")
lief_id = tag.findChild("Lieferant_ID")
if lief_id is None:
continue
for ptag in tag.findChild("Positionen").findChildren("Position"):
row = dict() # Make a new row
row["Lieferant_ID"] = lief_id.text
row["Artikel"] = ptag.attrs["Artikel"]
row["Bezeichnung"] = ptag.attrs["Bezeichnung"]
row["Menge"] = ptag.attrs["Menge"]
rows.append(row)
现在,您可以使用 pd.DataFrame.from_records()
pd.DataFrame.from_records(rows)
Lieferant_ID Artikel Bezeichnung Menge
0 459 MCGPXO96 Refined Rubber Tuna 1
1 459 IYTAFI28 Generic Cotton Chicken 8