【问题标题】:Python sort elements by value xmlPython按值xml对元素进行排序
【发布时间】:2021-02-04 08:52:22
【问题描述】:

我有一个很大的 xml 文件。我尝试将 ElementTree XML API 用于 python,我可以通过标签解析 xml 文件,并在它成功生成 csv 文件之后。现在,我对相同的名称标签及其信息有不同的问题。

例如,一个 xml 文件包含称为 user 的相同标签,用于许多不同的用户。

<User>
    <Number>145321</Number>
    <Name>Tony</Name>
    <Address>
    <City>Stockholm</City>
    <Country>Sweden</Country>
    <FullAddress>example address</FullAddress>
    </Address>
    <CustomerID>1234</CustomerID>
    <Accounts>
    <AccountID>8774</AccountID>
    </Accounts>
    <Payment></Payment>
</User>

在这个结构之后是另一个具有相同名称的相同结构,它描述了不同的用户及其元素。如何区分这些信息?比如我想根据AccountID号找到用户名,然后保存成csv格式,该怎么做呢?

【问题讨论】:

  • 你能告诉我们你迄今为止尝试过的代码/进展吗?
  • 发布在答案部分
  • @Remark:请编辑问题。除非您对问题有真正的答案,否则不要发布答案。

标签: python xml csv


【解决方案1】:

下面的代码将“XML 用户”转换为“Python 用户” 有了 User 类后,查找数据就很容易了。

from dataclasses import dataclass
import xml.etree.ElementTree as ET


@dataclass
class Address:
  city: str
  country: str
  full_address:str 

@dataclass
class User:
    number: int
    name: str
    address: Address
    accounts: []


xml = '''<Users>
    <User>
        <Number>145321</Number>
        <Name>Tony</Name>
        <Address>
            <City>Stockholm</City>
            <Country>Sweden</Country>
            <FullAddress>example address</FullAddress>
        </Address>
        <CustomerID>1234</CustomerID>
        <Accounts>
            <AccountID>8774</AccountID>
        </Accounts>
        <Payment></Payment>
    </User>
        <User>
        <Number>145441</Number>
        <Name>Jack</Name>
        <Address>
            <City>London</City>
            <Country>UK</Country>
            <FullAddress>example address</FullAddress>
        </Address>
        <CustomerID>5588</CustomerID>
        <Accounts>
            <AccountID>1966</AccountID>
        </Accounts>
        <Payment></Payment>
    </User>
</Users> '''


def _get_addr(ue):
  ae = ue.find('Address')
  return Address(ae.find('City').text,ae.find('Country').text,ae.find('FullAddress').text)


root = ET.fromstring(xml)
user_elements = root.findall('.//User')
users = []
for ue in user_elements:
  users.append(User(int(ue.find('Number').text),ue.find('Name').text,_get_addr(ue),[int(ac.text) for ac in ue.find('Accounts').findall('AccountID')]))

for user in users:
  print(user)
# Look for Jack - linear search just for demo
for user in users:
  if user.name == 'Jack':
    print('Found')

输出

User(number=145321, name='Tony', address=Address(city='Stockholm', country='Sweden', full_address='example address'), accounts=[8774])
User(number=145441, name='Jack', address=Address(city='London', country='UK', full_address='example address'), accounts=[1966])
Found

【讨论】:

    【解决方案2】:

    发现这个lib增加了大文件处理功能。我试试看。

    from simplified_scrapy import SimplifiedDoc, utils
    
    doc = SimplifiedDoc(edit=False)
    doc.loadFile('test.xml', lineByline=True)
    
    users = []
    for user in doc.getIterable('User'):
        AccountIDs = user.selects('AccountID').text
        if '8774' in AccountIDs: # Look up AccountID
            users.append([
                user.Number.text, user.Name.text, user.CustomerID.text,
                user.Payment.text, ','.join(user.Address.children.text),
                ','.join(AccountIDs)
            ])
    
    utils.save2csv('user.csv', users)
    

    Here 是更多示例。这个库很容易使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多