XML файл в CSV через python фрейм данных - PullRequest
0 голосов
/ 27 мая 2020

Недавно я задал закрытый вопрос, поэтому стараюсь сделать его менее широким. Моя проблема в том, что я не знаю, с чего начать, поэтому я не могу показать, что я «уже пробовал». Невозможно найти в Интернете что-либо, что помогло.

У меня есть файл с открытым исходным кодом XML, который соответствует этому формату:

<surnames>
    <cluster>
        <surname lang="ga" text="Achaorainn" anchor="Achaorainn"/>
        <surname lang="en" text="Ahern" anchor="Ahern"/>
        <surname lang="en" text="Aherne" anchor="Aherne"/>
        <surname lang="en" text="Ahearne" anchor="Ahearne"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Achison" anchor="Achison"/>
        <surname lang="en" text="Atchison" anchor="Atchison"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Adams" anchor="Adams"/>
        <surname lang="ga" text="Mac Conamha" anchor="Conamha"/>
    </cluster>
    <cluster>
        <surname lang="ga" text="Ághas" anchor="Ághas"/>
        <surname lang="en" text="Ashe" anchor="Ashe"/>
        <surname lang="ga" text="Ás" anchor="Ás"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Young" anchor="Young"/>
        <surname lang="ga" text="Ó Hógáin" anchor="Hógáin"/>
        <surname lang="ga" text="de Siún" anchor="Siún"/>
    </cluster>
</surnames>

По сути, я хочу, чтобы это было преобразовано в файл CSV, который выглядит так, каждый кластер разбивается на строку:

Achaorainn,Ahern,Aherne,Ahearne
Achison,Atchison
Adams,Mac Conamha

Я никогда не пробовал ничего подобного, поэтому даже просто указание мне правильного направления было бы огромной помощью.

Я подумал о преобразовании в фрейм данных, а затем в CSV.

Я пробовал это в качестве отправной точки, но я даже не могу заставить его работать, поскольку я думаю, что он не работает на этапе objectify.parse:

import csv
import pandas as pd
import xml.etree.ElementTree as ET

#%%

xml = objectify.parse('surnames_reduced.xml')
root = xml.getroot()

data=[]
for i in range(len(root.getchildren())):
    data.append([child.text for child in root.getchildren()[i].getchildren()])

df = pd.DataFrame(data).T

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Использование etree, сохранение в виде списка списков (которые можно напрямую преобразовать в CSV):

import lxml.etree
import csv

#  xml = lxml.etree.parse('z.xml')
xml = lxml.etree.fromstring(open('z.xml').read())  # in case there is no XML declaration!
result=[]
for cluster in xml.xpath('//cluster'):
    names = []
    for child in cluster.getchildren():
        names.append(child.get('text'))  # reads the name attribute
    result.append(names)

with open("out.csv", "w") as f:
    writer = csv.writer(f)
    writer.writerows(result)

print(open('out.csv').read())

Вывод:

Achaorainn,Ahern,Aherne,Ahearne
Achison,Atchison
Adams,Mac Conamha
Ághas,Ashe,Ás
Young,Ó Hógáin,de Siún
0 голосов
/ 30 июня 2020

Использование python builtin XML lib ( внешняя библиотека не требуется )

import xml.etree.ElementTree as ET

xml = '''<surnames>
    <cluster>
        <surname lang="ga" text="Achaorainn" anchor="Achaorainn"/>
        <surname lang="en" text="Ahern" anchor="Ahern"/>
        <surname lang="en" text="Aherne" anchor="Aherne"/>
        <surname lang="en" text="Ahearne" anchor="Ahearne"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Achison" anchor="Achison"/>
        <surname lang="en" text="Atchison" anchor="Atchison"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Adams" anchor="Adams"/>
        <surname lang="ga" text="Mac Conamha" anchor="Conamha"/>
    </cluster>
    <cluster>
        <surname lang="ga" text="Ághas" anchor="Ághas"/>
        <surname lang="en" text="Ashe" anchor="Ashe"/>
        <surname lang="ga" text="Ás" anchor="Ás"/>
    </cluster>
    <cluster>
        <surname lang="en" text="Young" anchor="Young"/>
        <surname lang="ga" text="Ó Hógáin" anchor="Hógáin"/>
        <surname lang="ga" text="de Siún" anchor="Siún"/>
    </cluster>
</surnames>'''

root = ET.fromstring(xml)
data = []
for c in root.findall('.//cluster'):
    data.append([s.attrib['text'] for s in c.findall('./surname')])
for entry in data:
    print(','.join(entry))

вывод

Achaorainn,Ahern,Aherne,Ahearne
Achison,Atchison
Adams,Mac Conamha
Ághas,Ashe,Ás
Young,Ó Hógáin,de Siún
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...