我有以下 xml 数据。
<transaction>
<date>20190415</date>
<ticket>303434037</ticket>
<value>15</value>
<notenders>01</notenders>
<tenderdetail>
<tendertype>00</tendertype>
<tenderamt>15</tenderamt>
</tenderdetail>
<item>
<receipeno>00001096</receipeno>
<price>7</price>
<qty>0001</qty>
<items>
<item>
<receipeno>00000786</receipeno>
<price>8</price>
<qty>0001</qty>
<items>
<item>
<receipeno>00000599</receipeno>
<price>0</price>
<qty>1</qty>
</item>
<item>
<receipeno>00000605</receipeno>
<price>0</price>
<qty>1</qty>
</item>
<item>
<receipeno>00000608</receipeno>
<price>0</price>
<qty>0004</qty>
</item>
</items>
</item>
<item>
<receipeno>10000043</receipeno>
<price>0</price>
<qty>0001</qty>
</item>
<item>
<receipeno>00000381</receipeno>
<price>7</price>
<qty>0001</qty>
<items>
<item>
<receipeno>00000607</receipeno>
<price>0</price>
<qty>1</qty>
</item>
</items>
</item>
</items>
</item>
</transaction>
我需要将其转换为表格格式。问题是每个标签内有许多嵌套分支。例如很多<item>
& <items>
标签。与嵌套性无关。我需要将数据逐一列出。
我想要的输出如下
+----------+--------+-------+-----------+------------+-----------+-----------+-------+-----+
| date | ticket | value | notenders | tendertype | tenderamt | receipeno | price | qty |
+----------+--------+-------+-----------+------------+-----------+-----------+-------+-----+
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 1096 | 7 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 786 | 8 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 599 | 0 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 605 | 0 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 608 | 0 | 4 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 143 | 0 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 381 | 7 | 1 |
| 20190101 | 12345 | 15 | 1 | 0 | 15 | 607 | 0 | 1 |
+----------+--------+-------+-----------+------------+-----------+-----------+-------+-----+
我是 python 和 XML 解析新手。因此,请指导我解决这个问题。 ...
最佳答案
从必要的导入开始:
import pandas as pd
import xml.etree.ElementTree as et
import re
然后,要从要读取的标签中删除前导零,请定义以下函数:
def stripLZ(src):
return re.sub(r'^0+(?=\d)', '', src)
要读取源文件及其根元素,请执行:
tree = et.parse('transaction.xml')
root = tree.getroot()
要从root级别读取标签(除了从item读取),请执行:
dt = root.find('date').text
tck = root.find('ticket').text
val = root.find('value').text
notend = stripLZ(root.find('notenders').text)
剩下的两个标签是下一级的,所以从读取它们的父标签开始:
tdet = root.find('tenderdetail')
并从中读取这些标签:
tendtyp = stripLZ(tdet.find('tendertype').text)
tendamt = tdet.find('tenderamt').text
请注意,我在这里使用了stripLZ函数(它将被使用 多几次)。
现在有时间创建结果 DataFrame:
df_cols = ['date', 'ticket', 'value', 'notenders',
'tendertype', 'tenderamt', 'receipeno', 'price', 'qty']
df = pd.DataFrame(columns = df_cols)
并且可以使用iter方法执行加载循环:
for it in root.iter('item'):
rcp = it.find('receipeno').text
prc = it.find('price').text
qty = stripLZ(it.find('qty').text)
df = df.append(pd.Series([dt, tck, val, notend,
tendtyp, tendamt, rcp, prc, qty],
index = df_cols), ignore_index=True)
这个循环:
- 迭代所有 item 标签,无论其深度如何。
- 从当前项目读取 3 个标签。
- 将一行附加到结果 DataFrame。
关于python - 在 python 中解析和转换嵌套 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56406117/