Ошибка синтаксического анализа XML, возникла проблема с правильной логикой Xpath и цикла - PullRequest
0 голосов
/ 03 мая 2019

Я использую ElementTree xml API для преобразования некоторых данных из локального XML-файла, сохраненного в каталоге, в CSV-файл, XML-файл выглядит следующим образом

    <object>
        <name>Eosinophil</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>415</xmin>
            <ymin>120</ymin>
            <xmax>532</xmax>
            <ymax>252</ymax>
        </bndbox>
    </object>

я пытаюсь этот код Python, чтобы сделать это:

def parseXML(xmlfile): 

    tree = ET.parse(xmlfile) 
    root = tree.getroot() 
    mainlist = [] 

    for object in root.findall('.//object'):  
        records = {} 
        for bndbox in object: 
            records[bndbox.tag] = bndbox.text.encode('utf8') 
        mainlist.append(records) 
    return mainlist 

def savetoCSV(newsitems, filename): 

    fields = ['name', 'pose', 'truncated', 'difficult', 'xmin','ymin', 'xmax','ymax'] 

    with open(filename, 'w') as csvfile: 
    writer = csv.DictWriter(csvfile, fieldnames = fields) 
    writer.writeheader() 
    writer.writerows(newsitems) 

не дает ошибки, а просто создает пустой CSV-файл с правильными заголовками, так как я новичок в этих вещах, я искал ресурсы и думаю, что есть проблема в цикле "object in root.findall", пожалуйста, помогите в это дело.

я вызываю эти функции, как показано ниже

def main(): 
    newsitems = parseXML('My photo - 09-04-2019_10-11-32.xml') 
    savetoCSV(mainlist, 'sample.csv') 

можете ли вы предложить изменения в Xpath, включенные в цикл, наряду с логикой цикла

1 Ответ

0 голосов
/ 04 мая 2019

Я вижу 2 проблемы в вашем скрипте.

1) вы не должны использовать bndbox в качестве объекта цикла for, поскольку существует узел с таким именем

2) когда вы получаете имя bndbox, которое имеет дочерние узлы, вы должны перебирать дочерние узлы, чтобы получить информацию.

Вот решение вашего вопроса. (Проверено и работает как положено)

import xml.etree.ElementTree as ET
import csv

def parseXML(xmlfile):
    tree = ET.parse(xmlfile)
    root = tree.getroot()
    mainlist = []

    for object in root.findall('.//object'):
        records = {}
        for node in object:

            if (len(node.findall("*"))>0):
                for subnode in node.findall('*'):
                    records[subnode.tag] = subnode.text.encode('utf8')
            else:
                records[node.tag] = node.text.encode('utf8')

        mainlist.append(records)
    print(mainlist)
    return mainlist

def savetoCSV(newsitems, filename):
    fields = ['name', 'pose', 'truncated', 'difficult', 'xmin','ymin', 'xmax','ymax']
    with open(filename, 'w') as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames = fields)
        writer.writeheader()
        writer.writerows(newsitems)

xmlfile = r"C:\Users\supputuri\PycharmProjects\Selenium_Test\Data\emps.xml"
items = parseXML(xmlfile)
savetoCSV(items,"output.csv")

Я только что добавил второй набор объектов, чтобы убедиться, что скрипт отлично работает с несколькими наборами. Вот снимок файла output.csv enter image description here

...