Python 正确解析用于CSV输出的XML文件

Python 正确解析用于CSV输出的XML文件,python,python-2.7,Python,Python 2.7,我构建了这个脚本,用于解析XML文件,检索id、创建日期、作者id和注释节点的内容,并将它们打印到CSV。它主要是工作在一个例外 我遇到了一个问题,脚本循环遍历XML中的每个id,并在XML中打印每个注释,就好像它是该id的一部分,而事实并非如此 理想情况下,最终目标是仅获取和打印属于每个唯一id的注释,并打印注释节点的内容 问题示例(CSV输出): 我只想打印与id相关的评论,而不是每个id的评论(如果有意义的话) 代码如下: #!/usr/bin/env python # -*- codin

我构建了这个脚本,用于解析XML文件,检索id、创建日期、作者id和注释节点的内容,并将它们打印到CSV。它主要是工作在一个例外

我遇到了一个问题,脚本循环遍历XML中的每个id,并在XML中打印每个注释,就好像它是该id的一部分,而事实并非如此

理想情况下,最终目标是仅获取和打印属于每个唯一id的注释,并打印注释节点的内容

问题示例(CSV输出):

我只想打印与id相关的评论,而不是每个id的评论(如果有意义的话)

代码如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys

from xml.etree import ElementTree as ET
import csv

xml_file = sys.argv[1]

if not xml_file.endswith('.xml'):
    print "%s is not a valid XML file. Exiting." % xml_file
    exit()

tree = ET.parse(xml_file)
root = tree.getroot()

# Ignore characters/string(s) (if any)
ignore_chars = ['>', '>>']


class RotateFile(object):
    def __init__(self, directory='', filename='', max_files=sys.maxint,
                 max_file_size='', header=''):
        self.ii = 1
        self.header = header
        self.directory, self.filename = directory, filename
        self.max_file_size, self.max_files = max_file_size, max_files
        self.finished, self.fh = False, None
        self.open()

    def rotate(self):
        """Rotate the file, if necessary"""
        if (os.stat(self.filename_template).st_size > self.max_file_size):
            self.close()
            self.ii += 1
            if (self.ii <= self.max_files):
                self.open()
            else:
                self.close()
                self.finished = True

    def open(self):
        self.fh = open(self.filename_template, 'w')
        self.writer = csv.writer(self.fh)
        self.writer.writerow(self.header)

    def write(self, text=""):
        self.writer = csv.writer(self.fh)
        self.writer.writerow([s.encode("utf-8") for s in text])
        self.fh.flush()
        self.rotate()

    def close(self):
        self.fh.close()

    @property
    def filename_template(self):
        return "%0.2d" % self.ii + "_" + self.filename


def comments():
    for comment in root.iter('comment'):
        created_at = comment.find("created-at").text
        value = comment.find("value").text
        author_id = comment.find("author-id").text
        if not value:
            continue
        yield created_at, value, author_id


def tickets(root):
    for ticket in root.iter('ticket'):
        nice_id = ticket.find("nice-id").text
        for comment in comments():
            created_at, value, author_id = comment
            yield nice_id, created_at, author_id, value


# Set arguments
args = {'directory': '',
        'filename': 'output.csv',
        'max_file_size': 10485760,
        'header': ['Ticket ID', 'Created Date', 'Author ID', 'Comment'],
        }

fout = RotateFile(**args)

for row in tickets(root):
    if not any(ignore_chars in row for ignore_char in ignore_chars):
        print ','.join(row)
        fout.write(row)
#/usr/bin/env python
#-*-编码:utf-8-*-
导入操作系统
导入系统
从xml.etree导入ElementTree作为ET
导入csv
xml_file=sys.argv[1]
如果不是xml_file.endswith('.xml'):
打印“%s”不是有效的XML文件。正在退出。“%XML\u文件”
退出()
tree=ET.parse(xml_文件)
root=tree.getroot()
#忽略字符/字符串(如果有)
忽略字符=['>','>>']
类旋转文件(对象):
def_uuuinit_uuuu(self,目录='',文件名='',max_files=sys.maxint,
最大文件大小=“”,头=“”):
self.ii=1
self.header=header
self.directory,self.filename=目录,文件名
self.max\u file\u size,self.max\u files=max\u file\u size,max\u files
self.finished,self.fh=假,无
self.open()
def旋转(自):
“”“如有必要,请旋转文件”“”
如果(os.stat(self.filename\u template).st\u size>self.max\u file\u size):
self.close()
self.ii+=1

如果(self.ii以下是为修复原始问题而进行的代码更改,如上述注释所述:

def comments(ticket):
for comment in ticket.iter('comment'):
    created_at = comment.find("created-at").text
    value = comment.find("value").text
    author_id = comment.find("author-id").text
    if not value:
        continue
    yield created_at, value, author_id

我可以通过对comments()进行更改来解决此问题。我将root.find更改为ticket.find,并将当前ticket传递到该函数中。这意味着每次调用它时,它不会查找所有注释,而是只查找ticket中的注释。
def comments(ticket):
for comment in ticket.iter('comment'):
    created_at = comment.find("created-at").text
    value = comment.find("value").text
    author_id = comment.find("author-id").text
    if not value:
        continue
    yield created_at, value, author_id