xml解析出错,在正确的Xpath和循环逻辑中存在问题

时间:2019-05-03 16:30:08

标签: python xpath xml-parsing

我正在使用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文件,因为我不熟悉这些东西,因此我搜索了资源,并且我认为“ root.findall中的对象”循环存在问题,请提供帮助这种情况。

我正在按以下方式调用这些函数

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

您能否建议循环中涉及的Xpath更改以及循环逻辑

1 个答案:

答案 0 :(得分:0)

我在您的脚本中看到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的快照 {{3}}