2012-07-20 33 views
6

2 ngày trước, tôi lần đầu tiên được giới thiệu với Python (và lập trình nói chung). Hôm nay tôi bị kẹt. Tôi đã dành hàng giờ cố gắng tìm một câu trả lời cho những gì tôi nghi ngờ là một vấn đề tầm thường, không ai khác vẫn chưa bị kẹt ở đây:)Python - Làm cách nào để lồng các vòng đọc tệp?

Ông chủ muốn tôi tự làm sạch các tệp .xml HUGE . Tôi đang cố gắng tạo một kịch bản để làm điều đó cho tôi. Sau đây là ví dụ về tệp .xml cũng như kết quả mong muốn của tôi.

Input (File.xml):

<IssueTracking> 
    <Issue> 
    <SequenceNum>123</SequenceNum> 
    <Subject>Subject of Ticket 123</Subject> 
    <Description>Line 1 in Description field of Ticket 123. 
Line 2 in Description field of Ticket 123. 
Line 3 in Description field of Ticket 123.</Description> 
    </Issue> 
    <Issue> 
    <SequenceNum>124</SequenceNum> 
    <Subject>Subject of Ticket 124</Subject> 
    <Description>Line 1 in Description field of Ticket 124. 
Line 2 in Description field of Ticket 124. 
Line 3 in Description field of Ticket 124.</Description> 
    </Issue> 
</IssueTracking> 

mong muốn Output:

123 Subject of Ticket 123 
Line 1 in Description field of Ticket 123. 
Line 2 in Description field of Ticket 123. 
Line 3 in Description field of Ticket 123. 

124 Subject of Ticket 124 
Line 1 in Description field of Ticket 124. 
Line 2 in Description field of Ticket 124. 
Line 3 in Description field of Ticket 124. 

Dưới đây là những gì tôi đã có cho đến nay.

with open(File.xml, 'r') as SourceFile: # Opens the file 
    while 1: # Keep going through the file to the end 
     SourceFileLine = SourceFile.readline() # Saves lines of the source file 
     if not SourceFileLine: # Skip empty lines 
      break 

     SourceFileLine = SourceFileLine.strip() # Strips the whitespace 

     if "<SequenceNum>" in SourceFileLine: 
      SequenceNum = SourceFileLine[13:-14] # Trims the tags, saves the field. 
      continue 

     if "<Subject>" in SourceFileLine: 
      Subject = SourceFileLine[9:-10] 
      continue 

     #if "<Description>" in SourceFileLine: 
     # last_pos = SourceFile.tell() 
     # while "</Description>" not in SourceFileLine: 
     #  SourceFile.seek(last_pos) 
     #  ????? 
     #  
     # Description = Description[22:] 
     # continue 

     if "</Issue>" in SourceFileLine: 
      print(SequenceNum, end = "\t") 
      print(Subject) 
     # print(Description) 
      print("\n") 

Tôi đang mắc kẹt trong việc xác định và giữ chân những ba dòng giữa <Description> thẻ vào một chuỗi duy nhất tôi có thể in trước khi tiếp tục xuống các tập tin nguồn. Bây giờ đã quét hàng tá ví dụ khác về các vòng đọc dòng tệp, tôi nghi ngờ những gì tôi cần là gắn cờ điểm tôi đạt đến trường đích và lồng một vòng lặp đọc khác tại điểm đó trong tệp. Nhưng tôi đã không tìm thấy một ví dụ khác về việc này đang được thực hiện, vì vậy tôi cho rằng tôi đang thiếu một cái gì đó cơ bản hoặc có một cách tốt hơn. Cảm ơn trước sự giúp đỡ!

+1

Python có một built-in phân tích cú pháp XML: http://docs.python.org /library/pyexpat.html –

+3

+1 cho đầu vào, đầu ra mong muốn và những gì bạn đã thử. –

+0

Có lẽ bạn nên sử dụng bộ nối tiếp thân thiện với con người như YAML để xuất dữ liệu khi bạn đã trích xuất nó. Bạn không bao giờ biết khi nào bạn sẽ cần xử lý lại dữ liệu này. –

Trả lời

7

Một ví dụ của việc sử dụng lxml mà tôi khuyên bạn nên để xử lý dữ liệu của bạn. (Nb: viết cho Py2.x nhưng dễ dàng để thích ứng cho Py3.x)

from lxml import etree 
xml = """<IssueTracking> 
    <Issue> 
    <SequenceNum>123</SequenceNum> 
    <Subject>Subject of Ticket 123</Subject> 
    <Description>Line 1 in Description field of Ticket 123. 
Line 2 in Description field of Ticket 123. 
Line 3 in Description field of Ticket 123.</Description> 
    </Issue> 
    <Issue> 
    <SequenceNum>124</SequenceNum> 
    <Subject>Subject of Ticket 124</Subject> 
    <Description>Line 1 in Description field of Ticket 124. 
Line 2 in Description field of Ticket 124. 
Line 3 in Description field of Ticket 124.</Description> 
    </Issue> 
</IssueTracking> 
""" 

root = etree.fromstring(xml) 
for issue in root.findall('Issue'): 
    as_list = [issue.find(n).text for n in ('SequenceNum', 'Subject', 'Description')] 
    as_list[2] = as_list[2].split('\n') 
    print as_list 

Prints:

['123', 'Subject of Ticket 123', ['Line 1 in Description field of Ticket 123.', 'Line 2 in Description field of Ticket 123.', 'Line 3 in Description field of Ticket 123.']] 
['124', 'Subject of Ticket 124', ['Line 1 in Description field of Ticket 124.', 'Line 2 in Description field of Ticket 124.', 'Line 3 in Description field of Ticket 124.']] 
6

Vui lòng không đọc các tệp XML như thế này, vì python có nhiều thư viện khác nhau sẽ trợ giúp đọc các tệp XML.

Nhìn vào thư viện python lxml nó cung cấp một cách rất dễ đọc và sau đó phân tích các tệp XML và nó sẽ cải thiện đáng kể mã của bạn.

tôi sẽ giải thích làm thế nào để sử dụng thư viện riêng của mình, nhưng tài liệu của họ là tốt hơn nhiều hơn tôi có thể chui vào vùng văn bản này: http://lxml.de/tutorial.html

+0

Cảm ơn bạn, tôi sẽ nghiên cứu điều này và tìm ra. Tôi đánh giá cao sự giúp đỡ của bạn. – phlogiston

Các vấn đề liên quan