Python извлекает данные из xml и сохраняет их в Excel

Я хотел бы извлечь некоторые данные из файла XML и сохранить их в формате таблицы, например XLS или DBF.

Вот файл XML, который у меня есть:

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header />
  <SOAP-ENV:Body>
    <ADD_LandIndex_001>
      <CNTROLAREA>
        <BSR>
          <VERB>ADD</VERB>
          <NOUN>LandIndex</NOUN>
          <REVISION>001</REVISION>
        </BSR>
      </CNTROLAREA>
      <DATAAREA>
        <LandIndex>
          <reportId>AMI100031</reportId>
          <requestKey>R3278458</requestKey>
          <SubmittedBy>EN4871</SubmittedBy>
          <submittedOn>2015/01/06 4:20:11 PM</submittedOn>
          <LandIndex>
            <agreementdetail>
              <agreementid>001       4860</agreementid>
              <agreementtype>NATURAL GAS</agreementtype>
              <currentstatus>
                <status>ACTIVE</status>
                <statuseffectivedate>1965/02/18</statuseffectivedate>
                <termdate>1965/02/18</termdate>
              </currentstatus>
              <designatedrepresentative>
              </designatedrepresentative>
            </agreementdetail>
          </LandIndex>
        </LandIndex>
      </DATAAREA>
    </ADD_LandIndex_001>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Меня интересует информация внутри тега agreementdetail, который находится в разделе DATAAREA/LandIndex/LandIndex/

ОБНОВЛЕНИЕ:

Благодаря MattDMo эта задача немного сдвинулась с мертвой точки. Поэтому я сделал этот скрипт ниже. Он повторяет файл и получает все экземпляры agreementdetail и выводит agreementid и agreementtype для каждого.

import xml.etree.ElementTree as ET
import arcpy

xmlfile = 'D:/Working/Test/Test.xml'
element_tree = ET.parse(xmlfile)
root = element_tree.getroot()
agreement = root.findall(".//agreementdetail")
result = []
elements = ('agreementid', 'agreementtype')

for a in agreement:
    obj = {}
    for e in elements:
        obj[e] = a.find(e).text
    result.append(obj)

arcpy.AddMessage(result)

Вывод, который я получаю, состоит из набора следующих строк: {'agreementid': '001 4860', 'agreementtype': 'NATURAL GAS'}

Теперь мне нужно преобразовать этот вывод в формат таблицы (.csv, .dbf, .xls и т. д.), чтобы идентификатор и тип соглашения были столбцами:

agreementid    | agreementtype 
001       4860 | NATURAL GAS

Буду очень признателен, если подскажете, как это сделать. Или, может быть, какой-нибудь пример?

P.S. Версия Python 2.7.


person Olga K.    schedule 08.01.2015    source источник


Ответы (2)


Следующее должно работать:

import xml.etree.ElementTree as ET
import arcpy

xmlfile = 'D:/Working/Test/Test.xml'
element_tree = ET.parse(xmlfile)
root = element_tree.getroot()
agreement = root.find(".//agreementid").text
arcpy.AddMessage(agreement)

В вызове root.find() используется выражение XPath (краткая шпаргалка находится в документации по Python здесь), чтобы найти первый тег на любом уровне под текущий уровень с именем agreementid. Если в вашем файле есть несколько тегов с такими именами, вы можете использовать root.findall() и перебирать результаты. Если, например, есть три поля с именем agreementid, и вы знаете, что вам нужно второе, то root.findall(".//agreementid")[1] должно работать.

person MattDMo    schedule 08.01.2015
comment
На самом деле моя цель — получить все доказательства наличия ‹agreementdetail› со всеми встроенными элементами, потому что на самом деле этот xml содержит много тегов ‹agreementdetail›, я просто сократил его для этого поста. - person Olga K.; 08.01.2015

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

Из документов:

import csv
with open('eggs.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=' ',
                        quotechar='|', quoting=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
person Mayur Patel    schedule 08.01.2015