使用BeautifulSoup将XML解析为字典
我有一段XML,如下所示:使用BeautifulSoup将XML解析为字典,xml,python-2.7,beautifulsoup,Xml,Python 2.7,Beautifulsoup,我有一段XML,如下所示: <ns:Vehicle> <ns:Model>AVALON</ns:Model> <ns:ModelYear>1998</ns:ModelYear> <ns:MakeString>TY</ns:MakeString> <ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID> </ns:Vehic
<ns:Vehicle>
<ns:Model>AVALON</ns:Model>
<ns:ModelYear>1998</ns:ModelYear>
<ns:MakeString>TY</ns:MakeString>
<ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID>
</ns:Vehicle>
我只是想知道是否有更好的方法来做到这一点,我不介意遍历XML中的其余元素并像这样单独定义它们,我只是想知道是否有更干净的方法来做到这一点。可能更干净一些,但本质上没有什么不同:
tags = ['model', 'modelyear', 'makestring', 'vehicleid']
vehicle = {}
for tag in tags:
vehicle[tag] = '{}'.format(soup.find('ns:' + tag).text)
还有一个可能值得一看。可能更干净一点,但本质上没有什么不同:
tags = ['model', 'modelyear', 'makestring', 'vehicleid']
vehicle = {}
for tag in tags:
vehicle[tag] = '{}'.format(soup.find('ns:' + tag).text)
还有一点可能值得一看。BeautifulSoup并不是真正用于XML的,它非常适合凌乱的HTML,这会破坏一个合适的解析器 您最好使用接口(通过,也许是非常快的),不管怎样,IIRC是BS默认使用的。然后获取根元素并在几行代码中迭代其所有子元素,例如:
#!/usr/bin/env python
import xml.etree.ElementTree as ET
import re
# Note the dummy namespace that must / should have been there...
xml = '''
<ns:Vehicle xmlns:ns="http://foo.bar">
<ns:Model>AVALON</ns:Model>
<ns:ModelYear>1998</ns:ModelYear>
<ns:MakeString>TY</ns:MakeString>
<ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID>
</ns:Vehicle>'''
tree = ET.fromstring(xml)
vehicle = {re.sub(r'{.*}', '', node.tag): node.text for node in tree}
#/usr/bin/env python
将xml.etree.ElementTree作为ET导入
进口稀土
#请注意必须/应该存在的虚拟命名空间。。。
xml=“”
阿瓦隆
1998
泰
VIN号在这里
'''
tree=ET.fromstring(xml)
vehicle={re.sub(r'{.*}','',node.tag):树中节点的node.text}
BeautifulSoup并不是真正用于XML的,它是凌乱HTML的理想选择,这会破坏一个合适的解析器
您最好使用接口(通过,也许是非常快的),不管怎样,IIRC是BS默认使用的。然后获取根元素并在几行代码中迭代其所有子元素,例如:
#!/usr/bin/env python
import xml.etree.ElementTree as ET
import re
# Note the dummy namespace that must / should have been there...
xml = '''
<ns:Vehicle xmlns:ns="http://foo.bar">
<ns:Model>AVALON</ns:Model>
<ns:ModelYear>1998</ns:ModelYear>
<ns:MakeString>TY</ns:MakeString>
<ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID>
</ns:Vehicle>'''
tree = ET.fromstring(xml)
vehicle = {re.sub(r'{.*}', '', node.tag): node.text for node in tree}
#/usr/bin/env python
将xml.etree.ElementTree作为ET导入
进口稀土
#请注意必须/应该存在的虚拟命名空间。。。
xml=“”
阿瓦隆
1998
泰
VIN号在这里
'''
tree=ET.fromstring(xml)
vehicle={re.sub(r'{.*}','',node.tag):树中节点的node.text}
如果希望所有子节点都位于
元素中,则无需显式指定它们-只需循环所有子元素并将它们放入字典中即可
from bs4 import BeautifulSoup
soup = BeautifulSoup('''
<ns:Vehicle>
<ns:Model>AVALON</ns:Model>
<ns:ModelYear>1998</ns:ModelYear>
<ns:MakeString>TY</ns:MakeString>
<ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID>
</ns:Vehicle>
''')
# loop if you have multiple vehicles
# Note that BS normalizes all tag names to lowercase -> we use 'ns:vehicle' rather 'ns:Vehicle'
for el_vehicle in soup.find_all('ns:vehicle'):
vehicle = {child.name: child.text for child in el_vehicle.findChildren()}
# stick `vehicle` in a list or do some other processing
从bs4导入美化组
汤=美汤(“”)
阿瓦隆
1998
泰
VIN号在这里
''')
#如果您有多辆车,请循环
#请注意,BS将所有标记名规范化为小写->我们使用“ns:vehicle”而不是“ns:vehicle”
对于汤中的el_车辆。查找所有('ns:vehicle'):
vehicle={child.name:child.text用于el_vehicle.findChildren()中的子对象
#将'vehicle'粘贴在列表中或进行其他处理
这与您的输出不完全匹配,因为它不会从camelcase转换为下划线分隔名称(例如,ModelYear
转换为model\u year
),而且它也不会从元素名称中去掉名称空间。如果需要,在child.name
周围包含一个包装器来相应地更改名称应该不会太困难。如果希望
元素中的所有子节点,则不需要显式指定它们-只需循环所有子元素并将它们放入字典中即可
from bs4 import BeautifulSoup
soup = BeautifulSoup('''
<ns:Vehicle>
<ns:Model>AVALON</ns:Model>
<ns:ModelYear>1998</ns:ModelYear>
<ns:MakeString>TY</ns:MakeString>
<ns:VehicleID>VIN NUMBER GOES HERE</ns:VehicleID>
</ns:Vehicle>
''')
# loop if you have multiple vehicles
# Note that BS normalizes all tag names to lowercase -> we use 'ns:vehicle' rather 'ns:Vehicle'
for el_vehicle in soup.find_all('ns:vehicle'):
vehicle = {child.name: child.text for child in el_vehicle.findChildren()}
# stick `vehicle` in a list or do some other processing
从bs4导入美化组
汤=美汤(“”)
阿瓦隆
1998
泰
VIN号在这里
''')
#如果您有多辆车,请循环
#请注意,BS将所有标记名规范化为小写->我们使用“ns:vehicle”而不是“ns:vehicle”
对于汤中的el_车辆。查找所有('ns:vehicle'):
vehicle={child.name:child.text用于el_vehicle.findChildren()中的子对象
#将'vehicle'粘贴在列表中或进行其他处理
这与您的输出不完全匹配,因为它不会从camelcase转换为下划线分隔名称(例如,
ModelYear
转换为model\u year
),而且它也不会从元素名称中去掉名称空间。如果需要,在child.name
周围包含一个包装器来相应地更改名称应该不会太困难。我尝试了xmltodict,而我正在使用的xml是一堆嵌套的OrderedDict。感谢您提供的这个解决方案,它比我的解决方案干净得多。我尝试了xmltodict,而我正在使用的xml是一堆嵌套的OrderedDict。谢谢你的解决方案,比我的要干净得多。