【问题标题】:Extracting XML Attributes提取 XML 属性
【发布时间】:2013-01-30 07:32:24
【问题描述】:

我有一个包含数千条记录的 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 unable to extract data using attrs=classExtracting an attribute value with 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()

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

【问题讨论】:

  • 您的问题是写入文件、在写入文件时格式化数据还是从结果中获取相关数据?
  • 我认为问题在于分离属性,以便我可以将它们写入输出文件。我已经编辑了我的代码块以添加输出文件。我应该在一开始就这样做。感谢您提及!

标签: python xml python-3.x beautifulsoup


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我(也)不会为此使用 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 中,属性的顺序会有所不同。 如果您希望它们以不同的特定顺序输出,您应该排序或 订购列表“钥匙”。

    断言正在检查所有行是否具有相同的属性。 如果您确实在元素中缺少或不同的属性, 那么你必须删除它并添加一些代码来处理差异 并为缺失值提供默认值。 (在您的样本数据中,您有一个 空值 ( m_name="" ),而不是缺失值。你可能想检查 这个输出的消费者可以处理这种情况,或者添加一些 对这种情况进行更特殊的处理。

    【讨论】:

    • 谢谢!考虑到你所掌握的信息,这很有效。我从来没有想过要提到我不是在根级别工作,而是在两个甚至 3 个级别下工作。此外,我拥有 zero 控制权的输入文件非常脏。我认为 lxml 或BeautifulSoup 可以更好地处理肮脏的输入。我敢肯定,如果我知道更多,那么您的方法将同样轻松地处理各个级别。
    猜你喜欢
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多