【问题标题】:Converting a weirdly formatted XML file to CSV using python使用 python 将格式怪异的 XML 文件转换为 CSV
【发布时间】:2020-12-20 12:04:34
【问题描述】:

我有一个包含电话号码详细信息的奇怪 XML 文档,我需要将其导出为 CSV 文档,但问题是它的格式不正确。所有元素都在 string> 标记内,并且一些“名称”字段重复但不完全相同(如下例所示,大多数重复行包含额外的空格或逗号)。并且所有“数字”都从“名称”字段缩进。

        <string>example1</string>
            <string>014584111</string>

        <string>example2</string>
            <string>04561212123</string>

        <string>example3</string>
            <string>+1 156151561</string>

        <string>example4</string>
            <string>564513212</string>
        
        <string>example3, </string>
        <string>example4  </string>

如何使用 python 将其转换为 CSV 格式而不重复内容? 这是一个示例输出

FullName  PhoneNumber
  
example1  014584111
example2  014584111    
example3  +1 156151561  
example4  564513212 

【问题讨论】:

  • 如果这个&lt;string&gt;example3, &lt;/string&gt; 出现在这个&lt;string&gt;example3&lt;/string&gt; &lt;string&gt;+1 156151561&lt;/string&gt; 之前,那么输出是什么?如果没有特定的模式,如何识别重复?

标签: python python-3.x xml csv xmltocsv


【解决方案1】:

当然,这是可以做到的。如果你能用人类语言描述这个过程,你也可以编程。

例子:

  • 读取文件(逐行读取?或者文件是否适合内存?)
  • 剥离&lt;string&gt;&lt;/string&gt;
    • 该行是有意的吗? --> 否 --> 这是一把钥匙
    • 该行是有意的吗? --> 是 --> 是最后一个键的值
  • 将结果添加到字典中
  • 将字典写入 .csv 文件

所以 - 您现在需要做出一些决定,例如:

导入文件很大吗?那么它很可能不适合内存,我们需要逐行处理。或者它会适合内存吗?

这个程序会被多次需要吗?还是只是一次性转换?

然后你可以将问题分成更小的子问题,并为每个子问题编写一些测试。

您还需要考虑更多情况,例如文件大小,是否是一次性脚本,是否应该进行错误检查(如果有两条预期的行怎么办?)等等。

【讨论】:

    【解决方案2】:

    下面(用data做你需要做的事)

    import xml.etree.ElementTree as ET
    
    def is_phone_number(value):
        for x in value:
            if x != '+' and x != ' ' and not x.isnumeric():
                return False
        return True
        
    xml = '''<r> <string>example1</string>
                <string>014584111</string>
    
            <string>example2</string>
                <string>04561212123</string>
    
            <string>example3</string>
                <string>+1 156151561</string>
    
            <string>example4</string>
                <string>564513212</string>
            
            <string>example3, </string>
            <string>example4  </string></r>'''
    data = []
    root = ET.fromstring(xml)
    strings = root.findall('.//string')
    i = 0
    while i < len(strings):
        if is_phone_number(strings[i+1].text):
            data.append({'key': strings[i].text,'value':strings[i+1].text})
        i += 2
    
    print(data)
    

    输出

    [{'key': 'example1', 'value': '014584111'}, {'key': 'example2', 'value': '04561212123'}, {'key': 'example3', 'value': '+1 156151561'}, {'key': 'example4', 'value': '564513212'}]
    

    【讨论】:

    • @bitranox 查看 XML 输入(最后一条记录)并查看结果是否正确。随意投票这个答案:-)
    • 查看数据 - 它是格式错误的 XML,并且值是缩进的。问题中说明:所有“数字”都从“名称”字段缩进。通过使用普通的 XML 解析器,该信息会丢失 - 因此您需要手动解析它。最后两行不应出现在结果中,因为它们没有分配数字(这在问题的结果集中说明)。因此,不幸的是,您的答案是错误的......
    • @bitranox 我的代码只是将 XML 加载到字典列表中。从那时起,OP 可以添加可以解决此问题的逻辑。我对 XML 输入所做的只是添加&lt;r&gt;&lt;/r&gt;。我没有改变其他任何东西!
    • 再次 - 您的转换忽略缩进 - 数字在该数据集中缩进。该信息对于进一步解析很有用,您忽略它 - 这不是一个好主意!除此之外,您真的不需要 XML 解析器来剥离那些 标记。
    猜你喜欢
    • 2022-08-11
    • 1970-01-01
    • 2021-05-08
    • 2021-11-21
    • 2016-01-07
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 1970-01-01
    相关资源
    最近更新 更多