使用属性的读取 XML
Reading XML that uses attributes
关于 XML 的菜鸟问题。我正在使用 ElementTree 将 XML 转换为 df 并最终上传到数据库。我的问题是 XML 格式不标准。我见过的所有 ElementTree 示例都使用不同的格式。它看起来像这样:
<session session_id="9">
<party party_id="1" name="party 1">
<member member_id="1" name="bob"/>
<member member_id="2" name="simon"/>
</party>
<party party_id="2" name="party 2">
<member member_id="3" name="diana"/>
<member member_id="4" name="pablo"/>
</party>
</session>
一方面,所有信息都写在属性中,这不是什么大问题,因为我仍然可以获取它们。但是,我不仅要获取 member
元素的属性,还要获取它们的 parent 的属性。所以结果应该是这样的:
member_id
member_name
party_id
session_id
1
bob
1
9
2
simon
1
9
3
diana
2
9
4
pablo
2
9
我使用 children = list(root.iter())
列出所有 children,然后将它们的属性附加到数据框。但是我把 link 输给了 parent,所以我不能真正说出 member
来自哪个 party
分支,所以我不能分配正确的 party_id
。
我想知道是否有一种简单的方法可以从此 XML 结构中获取数据框?
您的 xml 完全有效且格式正确,但下面的示例说明了 xml 通常的结构。
<parent attribute="supporting information">
Information
<child attribute="supporting information">
Information
</child>
</parent>
唉,ElementTree 没有提供将属性转换为标签的巧妙方法 content/information。
解决方案
您已经完成了一半(如果我们算上根元素 'session',则可能是三分之一)。您将必须在每个 xml 元素级别进行迭代。 (例如,对于每个派对元素,迭代每个成员)。
像这样
import xml.etree.ElementTree as ET
import pandas as pd
xml = '''<session session_id="9">
<party party_id="1" name="party 1">
<member member_id="1" name="bob"/>
<member member_id="2" name="simon"/>
</party>
<party party_id="2" name="party 2">
<member member_id="3" name="diana"/>
<member member_id="4" name="pablo"/>
</party>
</session>'''
data = []
root = ET.fromstring(xml)
session_id = root.attrib['session_id']
for party in root.findall('party'):
for memeber in party.findall('member'):
data.append({'session_id':session_id,'party_id': party.attrib['party_id']})
data[-1]['member_name'] = memeber.attrib['name']
data[-1]['member_id'] = memeber.attrib['member_id']
df = pd.DataFrame(data)
print(df)
输出
session_id party_id member_name member_id
0 9 1 bob 1
1 9 1 simon 2
2 9 2 diana 3
3 9 2 pablo 4
关于 XML 的菜鸟问题。我正在使用 ElementTree 将 XML 转换为 df 并最终上传到数据库。我的问题是 XML 格式不标准。我见过的所有 ElementTree 示例都使用不同的格式。它看起来像这样:
<session session_id="9">
<party party_id="1" name="party 1">
<member member_id="1" name="bob"/>
<member member_id="2" name="simon"/>
</party>
<party party_id="2" name="party 2">
<member member_id="3" name="diana"/>
<member member_id="4" name="pablo"/>
</party>
</session>
一方面,所有信息都写在属性中,这不是什么大问题,因为我仍然可以获取它们。但是,我不仅要获取 member
元素的属性,还要获取它们的 parent 的属性。所以结果应该是这样的:
member_id | member_name | party_id | session_id |
---|---|---|---|
1 | bob | 1 | 9 |
2 | simon | 1 | 9 |
3 | diana | 2 | 9 |
4 | pablo | 2 | 9 |
我使用 children = list(root.iter())
列出所有 children,然后将它们的属性附加到数据框。但是我把 link 输给了 parent,所以我不能真正说出 member
来自哪个 party
分支,所以我不能分配正确的 party_id
。
我想知道是否有一种简单的方法可以从此 XML 结构中获取数据框?
您的 xml 完全有效且格式正确,但下面的示例说明了 xml 通常的结构。
<parent attribute="supporting information">
Information
<child attribute="supporting information">
Information
</child>
</parent>
唉,ElementTree 没有提供将属性转换为标签的巧妙方法 content/information。
解决方案
您已经完成了一半(如果我们算上根元素 'session',则可能是三分之一)。您将必须在每个 xml 元素级别进行迭代。 (例如,对于每个派对元素,迭代每个成员)。
像这样
import xml.etree.ElementTree as ET
import pandas as pd
xml = '''<session session_id="9">
<party party_id="1" name="party 1">
<member member_id="1" name="bob"/>
<member member_id="2" name="simon"/>
</party>
<party party_id="2" name="party 2">
<member member_id="3" name="diana"/>
<member member_id="4" name="pablo"/>
</party>
</session>'''
data = []
root = ET.fromstring(xml)
session_id = root.attrib['session_id']
for party in root.findall('party'):
for memeber in party.findall('member'):
data.append({'session_id':session_id,'party_id': party.attrib['party_id']})
data[-1]['member_name'] = memeber.attrib['name']
data[-1]['member_id'] = memeber.attrib['member_id']
df = pd.DataFrame(data)
print(df)
输出
session_id party_id member_name member_id
0 9 1 bob 1
1 9 1 simon 2
2 9 2 diana 3
3 9 2 pablo 4