0

我有一个包含数千条记录的 XML 文件,格式如下:

<custs>
    <record cust_ID="B123456@Y1996" l_name="Jungle" f_name="George" m_name="OfThe" city="Fairbanks" zip="00010" current="1" />
    <record cust_ID="Q975697@Z2000" l_name="Freely" f_name="I" m_name="P" city="Yellow River" zip="03010" current="1" />
    <record cust_ID="M7803@J2323" l_name="Jungle" f_name="Jim" m_name="" city="Fallen Arches" zip="07008" current="0" />
</custs>
    #   (I know it's not normalized.  This is just sample data)

如何将其转换为 CSV 或制表符分隔的文件?我知道我可以使用 re.compile() 语句在 Python 中对其进行硬编码,但是在 diff XML 文件布局中必须有一些更简单、更便携的东西。

我在这里找到了几个关于属性的线程,(Beautifulsoup 无法使用 attrs=class 提取数据,使用beautifulsoup 提取属性值)并且他们让我几乎到了那里:

#  Python 3.30
#
from bs4 import BeautifulSoup
import fileinput

Input = open("C:/Python/XML Tut/MinGrp.xml", encoding = "utf-8", errors = "backslashreplace")
OutFile = open('C:/Python/XML Tut/MinGrp_Out.ttxt', 'w', encoding = "utf-8", errors = "backslashreplace")

soup = BeautifulSoup(Input, features="xml")

results = soup.findAll('custs', attrs={})

# output = results   [0]#[0]

for each_tag in results:
    cust_attrb_value = results[0]
#       print (cust_attrb_value)
    OutFile.write(cust_attrb_value)

OutFile.close()

下一步(最后?)步骤是什么?

4

2 回答 2

2

如果此数据的格式正确(例如,使用规范的 XML),您应该考虑lxml而不是 BeautifulSoup。使用lxml,您可以读取文件,然后可以在其上应用 DOM 逻辑,包括 XPath 查询。通过您的 XPath 查询,您可以获取lxml代表您感兴趣的每个节点的对象,从中提取您需要的数据,并使用类似csv模块的东西将它们重写为您选择的任意格式。

具体来说,在 lxml 文档中,查看这些教程:

于 2013-01-30T16:26:18.750 回答
1

我(也)不会为此使用 BeautifulSoup,虽然我喜欢 lxml,但这是一个额外的安装,如果您不想打扰,这很简单,可以使用标准的 lib ElementTree 模块。

就像是:

import xml.etree.ElementTree as ET
import sys
tree=ET.parse( 'test.xml' )
root=tree.getroot()
rs=root.getchildren()
keys = rs[0].attrib.keys()
for a in keys: sys.stdout.write(a); sys.stdout.write('\t')
sys.stdout.write('\n')
for r in rs:
    assert keys == r.attrib.keys()
    for k in keys: sys.stdout.write( r.attrib[k]); sys.stdout.write('\t')
    sys.stdout.write('\n')

将从 python-3 生成:

zip m_name  current city    cust_ID l_name  f_name  
00010   OfThe   1   Fairbanks   B123456@Y1996   Jungle  George  
03010   P   1   Yellow River    Q975697@Z2000   Freely  I   
07008       0   Fallen Arches   M7803@J2323 Jungle  Jim 

请注意,对于 Python-2.7,属性的顺序会有所不同。如果您希望它们以不同的特定顺序输出,您应该对列表“keys”进行排序或排序。

断言正在检查所有行是否具有相同的属性。如果您实际上在元素中缺少或不同的属性,那么您必须删除它并添加一些代码来处理差异并为缺失值提供默认值。(在您的示例数据中,您有一个空值( m_name="" ),而不是一个缺失值。您可能需要检查此输出的使用者是否正确处理了这种情况,或者添加一些更特殊的处理这个案例。

于 2013-01-30T18:33:50.950 回答