2012-07-20 9 views
6

2 giorni fa sono stato introdotto per la prima volta in Python (e programmazione in generale). Oggi sono bloccato. Ho passato ore a cercare una risposta a ciò che sospetto sia un problema così banale, nessun altro è stato bloccato qui:)Python - Come nidificare i loop di lettura dei file?

Il capo vuole che pulisca manualmente ENORME file .xml in qualcosa di più umano leggibile . Sto cercando di creare una sceneggiatura per farlo per me. Quello che segue è un esempio del file .xml e anche il mio output desiderato.

ingresso (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> 

output desiderato:

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. 

Ecco quello che ho finora.

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") 

Sono bloccato a identificare e trattenere quelle tre righe tra i tag <Description> in una singola stringa posso stampare prima di continuare verso il basso il file di origine. Ora avendo scansionato dozzine di altri esempi di loop di lettura della linea di file, ho il sospetto che ciò di cui ho bisogno sia di contrassegnare il punto in cui raggiungo il campo di destinazione e di annidare un altro ciclo di lettura in quel punto del file. Ma non ho trovato un altro esempio di ciò che è stato fatto, quindi presumo che manchi qualcosa di base o che ci sia un modo migliore. Grazie in anticipo per l'aiuto!

+1

Python ha un built-in parser XML: http://docs.python.org /library/pyexpat.html –

+3

+1 per input, output desiderato e cosa hai provato. –

+0

Probabilmente dovresti usare un serializzatore di tipo umano come YAML per emettere i dati una volta che li hai estratti. Non si sa mai quando sarà necessario elaborare nuovamente questi dati. –

risposta

7

Un esempio di utilizzo lxml che consiglio vivamente al trattamento dei dati. (Nb: scritto per Py2.x ma facile da adattare per 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 

Stampe:

['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

Si prega di non leggere file XML come questo, per Python ci sono varie librerie che aiuteranno a leggere i file XML.

Guardare la libreria Python lxml fornisce un modo molto semplice per leggere e quindi analizzare i file XML e migliorerà notevolmente il codice.

vorrei spiegare come utilizzare la libreria stessa, ma la loro documentazione è di gran lunga migliore di quello che posso spremere in questa area di testo: http://lxml.de/tutorial.html

+0

Grazie, studierò questo e capirlo. Apprezzo il vostro aiuto. – phlogiston