3

我是 Python 新手(通常是编程)。为了使工作项目更容易,我正在尝试编写一些代码来搜索 XML 文件中的某些标签并将内容复制到第二个文件中。我需要读取的文件大约是 165MB,并且将有成千上万的条目要提取。

我已经成功地使它适用于小文件(从论坛上的示例代码工作,例如这个),但它在一定大小之上分崩离析(它开始复制大部分 XML,而不仅仅是所需的字符串)。我想这是因为我如何定义我的变量。

有人可以给我一个指针或示例代码来解决这个问题吗?我很惊讶它的工作原理!

这是我现在的代码:

text = open("UPC_Small.xml", "r")

lines = text.read()

fo = open("output.log", "wt")

crid1 = 0

while True:

    crid1 = lines.find('<ProgramInformation programId="crid://bds.tv/',crid1)
    crid2 = lines.find('">',crid1)
    crid_string = (lines[crid1+45:crid2])

    if crid1 == -1:
        fo.write("End of File")
        fo.close()
        break

    title1 = lines.find('<Title xml:lang="EN" type="main">',crid2)
    title2 = lines.find('</Title>',title1)
    title_string = (lines[title1+33:title2])

    genre1 = lines.find('<Name xml:lang="EN">',title2)
    genre2 = lines.find('</Name>',genre1)
    genre_string = (lines[genre1+20:genre2])

    fo.write(crid_string + "|" + title_string + "|" + genre_string + "\n")
4

2 回答 2

1

尝试使用 xml.etree.ElementTree来迭代 XML。

def parse_file(filename):
    import xml.etree.ElementTree as ET
    tree = ET.parse(filename)
    root = tree.getroot()
    for program_information in root.findall('ProgramInformation'):
        attr = program_information.attrib
        title = program_information.find('Title').text
        genre = program_information.get('Name').text
        yield attr, title, genre

for attr, title, genre in parse_file("UPC_Small.xml"):
    print attr, title, genre

PS 此代码未经测试,我从未使用过该库。

于 2013-09-29T21:56:47.580 回答
0

这里有一些代码可以帮助您尝试 SAX 解析器。对于简单的解析和大文件,它比 ElementTree 更好,因为它消耗的内存更少。

import xml.sax
from xml.sax.handler import ContentHandler

class MySaxHandler(ContentHandler):
  def __init__(self):
    ContentHandler.__init__(self)

    self.results = []

  def startElement(self, name, attrs):
    if name == 'ProgramInformation':
      program_id = attrs["programId"]
      self.results.append([program_id, "", ""])

  def characters(self, content):
    self.last_contents = str(content)

  def endElement(self, name):
    if name == 'Title':
      self.results[-1][1] = self.last_contents
    elif name == 'Name':
      self.results[-1][2] = self.last_contents

def parse(filename):
  handler = MySaxHandler()
  xml.sax.parse(filename, handler)
  return handler.results

if __name__ == '__main__':
  fo = open("output.log", "wt")
  fo.write("\n".join("|".join(parse("UPC_Small.xml")))
于 2013-09-29T22:16:32.567 回答