Python XPath и ElementTree не работают, если в первом родительском теге XML отсутствует дочерний тег - PullRequest
1 голос
/ 05 июня 2019

В настоящее время я использую Python для преобразования файла XML в формат CSV с использованием библиотеки ElementTree и XPath.Мой код работает, если весь дочерний тег существует (имя, фамилия и адрес) для первого родительского тега, но я получаю сообщение об ошибке

дочерний индекс вне диапазона

когда первый человек пропускает дочерний тег (существуют только имя и фамилия).

Какой код я могу написать, чтобы обойти это сообщение об ошибке?Это мой первый раз, когда я использую XPath, как можно добавить к нему оператор if?Или я должен использовать что-то еще?

Вот как выглядит мой XML-файл:

<?xml version="1.0" encoding="utf-8"?>
<Members>
    <Person>
      <FirstName>JANE</FirstName>
      <LastName>DOE</LastName>
    </Person>
    <Person>
      <FirstName>JOHN</FirstName>
      <LastName>DOE</LastName>
      <Address>
        <Address1>123 Straw Street</Address1>
        <Address2></Address2>
        <City>Apple</City>
        <State>Test</State>
        <ZipCode>123456    </ZipCode>
      </Address>
    </Person>
</Members>

Текущий код Python:

import  csv
import xml.etree.ElementTree as ET

tree = ET.parse("TestStack.xml")
root = tree.getroot()

xml_data_to_csv =open('OutputStack.csv','w')

Csv_writer=csv.writer(xml_data_to_csv)
list_head=[]

count=0
for element in root.findall('Person'):
    person = []

    #Get head by tag
    if count == 0:
       FirstName = element.find('FirstName').tag
       list_head.append(FirstName)

       LastName = element.find('LastName').tag
       list_head.append(LastName)

       Address = element[2].tag
       list_head.append(Address)

       Csv_writer.writerow(list_head)
       count = count +1

    #get child node
    FirstName = element.find('FirstName').text
    person.append(FirstName)

    LastName = element.find('LastName').text
    person.append(LastName)

    person.append([e.text for e in element.findall('Address//')])

    #Write List_nodes to csv
    Csv_writer.writerow(person)
xml_data_to_csv.close()

1 Ответ

1 голос
/ 06 июня 2019

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

import  csv
import xml.etree.ElementTree as ET

tree = ET.parse("in.xml")
root = tree.getroot()

xml_data_to_csv =open('out.csv','w')

Csv_writer=csv.writer(xml_data_to_csv)
list_head=['FirstName', 'LastName', 'Address']
Csv_writer.writerow(list_head)

for element in root.findall('Person'):
    person = []

    #get child node
    FirstName = element.find('FirstName').text
    person.append(FirstName)

    LastName = element.find('LastName').text
    person.append(LastName)

    person.append([e.text for e in element.findall('Address//')])

    #Write List_nodes to csv
    Csv_writer.writerow(person)
xml_data_to_csv.close()

В противном случае вы можете обработать исключение или проверить, сколько элементов существует, как это

if len(element) > 2:
    head_list.append(element[2])
    continue

Предварительно инициализируйте head_list = [None] * 3 #len(element) и соберите заголовки (как показ) и людей во время цикла for, затем напишите все в конце. Я бы не рекомендовал этот маршрут.

...