Próbuję przeczytać plik XML i konwertować go do pliku CSV.

Udało mi się wyodrębnić zawartość pliku XML w ramach pętli do pętli. Próbuję to przechowywać w kolumnach, a nie rzędach, jak jest obecnie przechowywany. Podano poniżej, jak wyglądają moje dane:

Date - 2019-01-01T08:00:00
ID - 5601986
Description - Product A
Product Type - 

ProductCode - ABC
ProductName - Computer

RefID - X-123
Comments - 

Oczekiwany wynik:

Date,ID,Description,ProductCode,ProductName,RefID,Comments
2019-01-01T08:00:00,5601986, Product A,ABC,Computer,X-123,

Kod, który zbudowałam do tej pory:

import xml.etree.ElementTree as ET

tree = ET.parse('/users/desktop/file.xml')
root = tree.getroot()
for elem in root:
    print(elem.tag, '-', elem.text)
    for subelem in elem:
        print(subelem.tag, '-', subelem.text)

Próbuję to przekonwertować na dataframe w celu dalszej analizy

Aktualizacja:

w tym nowy plik XML:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<CISDocument>
  <Name>Type</Name>
  <Code>ABC</Code>
  <Description>Done</Description>
  <SystemTimeZoneOffset>0.000000</SystemTimeZoneOffset>
  <RefDate>2018-12-26T17:42:59</RefDate>
  <ReportedDateTime>2018-12-26T17:43:00</ReportedDateTime>
  <OccurredDateTime>2018-12-26T17:43:12</OccurredDateTime>
  <Customer>
    <Customerpin>XYZ</Customerpin>
    <CustomerName>Hello</CustomerName>
  </Customer>
</CISDocument>

Prąd wyjściowy:

Customerpin,CustomerName
XYZ,Hello
0
hello kee 1 marzec 2019, 12:31

2 odpowiedzi

Najlepsza odpowiedź

Innym sposobem (GetChildren Deprecated):

I używam wydajności w przypadku dużego XML

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

def iter_docs(cis):
    for docall in cis:
        doc_dict = {}
        for doc in docall:
            tag = [elem.tag for elem in doc]
            txt = [elem.text for elem in doc]
            if len(tag) > 0: doc_dict.update(dict(zip(tag, txt)))
            else:
                doc_dict[doc.tag] = doc.text
        yield doc_dict

#sample with 2 records
xml_data = io.StringIO(u'''\
<CISDocument>
    <REC>
        <Date>LoadStopConfirmed</Date>
        <ID>5601986</ID>
        <Description>Product A</Description>
        <ProductType>
            <ProductCode>ABC</ProductCode>
            <ProductName>Computer</ProductName>
        </ProductType>
        <RefID>X-123</RefID> 
        <Comments>Product A</Comments>  
    </REC>
    <REC>
        <Date>other</Date>
        <ID>5601987</ID>
        <Description>Product B</Description>
        <ProductType>
            <ProductCode>DEF</ProductCode>
            <ProductName>Computer</ProductName>
        </ProductType>
        <RefID>X-124</RefID>
        <Comments>Product B</Comments>
    </REC>
</CISDocument>
''')


etree = ET.parse(xml_data)

df = pd.DataFrame(list(iter_docs(etree.getroot())))
print(df)

Wynik:

    Comments               Date Description  ... ProductCode ProductName  RefID
0  Product A  LoadStopConfirmed   Product A  ...         ABC    Computer  X-123
1  Product B              other   Product B  ...         DEF    Computer  X-124
[2 rows x 7 columns]

Jeśli chcesz zastosować to na wielu plikach XML, wystarczy umieść listę plików na liście i zrób to

xml_data = "E:/test.xml"

df = pd.DataFrame()      #create the final df empty

#here i use a list of same file 
xmllist =  [xml_data, xml_data, xml_data]
for xmlfile in xmllist:
    etree = ET.parse(xmlfile).getroot()
    tmp = pd.DataFrame(list(iter_docs(etree)))
    df = df.append(tmp)

print(df)
1
Frenchy 4 marzec 2019, 10:35

Próbować:

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

tree = ET.parse(filename)
root = tree.getroot()
final = []
for elem in root:
    temp = {}
    for i in elem.getchildren():
        if i:
            for c in i.getchildren():
                temp[c.tag] = c.text
        else:
            temp[i.tag] = i.text
    final.append(temp)

df = pd.DataFrame(final)
print(df)

Wynik:

  Comments               Date Description       ID ProductCode ProductName  \
0           LoadStopConfirmed   Product A  5601986         ABC    Computer   

   RefID  
0  X-123  

Nowy plik XML:

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

tree = ET.parse(filename)
root = tree.getroot()
final = {}
for elem in root:
    if len(elem):
        for c in elem.getchildren():
            final[c.tag] = c.text
    else:
        final[elem.tag] = elem.text

df = pd.DataFrame([final])
print(df)
1
Rakesh 1 marzec 2019, 14:06