2013-09-29 49 views
3

我是Python新手(通常編程)。爲了使工作項目更容易,我試圖編寫一些代碼來搜索XML文件中的某些標記並將其內容複製到第二個文件中。我需要讀取的文件大約爲165MB,並且將有數以萬計的條目需要拔出。在大文件中查找字符串並在Python中將每個文件寫入第二個文件

我已經成功地使它適用於小文件(使用例如這個論壇上的示例代碼),但它在特定大小之上分裂(它開始複製大部分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") 
+2

試試SAX解析器。它不會誤解你的XML,並且應該仍然是合理的快速和高效的內存。 – Ryan

+0

看起來像@minitech提到的這是一種很好的Python方法:http://docs.python.org/2/library/xml.sax.html – BlackVegetable

+1

'read()'將整個文件讀入內存。這不適用於非常大的文件。相反,考慮重新組織你的程序,一次只讀一行,使用'readline()'。 – pburka

回答

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 

P.S.此代碼未經測試,我從未使用該庫。

0

下面是一些讓你在rails上試用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"))) 
相關問題