2012-07-20 19 views
6

2 दिन पहले मुझे पहली बार पायथन (और सामान्य रूप से प्रोग्रामिंग) से पेश किया गया था। आज मैं अटक गया हूँ। मैंने जो कुछ संदेह किया है, उसे उत्तर देने का प्रयास करने में घंटों बिताए हैं, इसलिए कोई समस्या अभी भी फंस गई है:)पायथन - कैसे फ़ाइल पढ़ने लूप घोंसला करने के लिए?

बॉस चाहता है कि मैं मैन्युअल रूप से बड़ी .xml फ़ाइलों को मैन्युअल रूप से कुछ और पठनीय में साफ कर दूं । मैं इसे मेरे लिए करने के लिए एक स्क्रिप्ट बनाने की कोशिश कर रहा हूं। निम्नलिखित .xml फ़ाइल के साथ-साथ मेरा वांछित आउटपुट का एक उदाहरण है।

इनपुट (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> 

वांछित आउटपुट:

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. 

यहाँ मैं अब तक क्या मिल गया है है।

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

मैं पहचान करने और एक एकल स्ट्रिंग मैं स्रोत फ़ाइल नीचे जारी रखने से पहले मुद्रित कर सकते हैं में <Description> टैग के बीच उन तीन लाइनों को बनाए रखना में अटक कर रहा हूँ। अब फ़ाइल लाइन के अन्य उदाहरणों के दर्जनों स्कैन किए गए हैं, मुझे संदेह है कि मुझे जिस बिंदु की आवश्यकता है वह उस बिंदु को ध्वजांकित करना है जो मैं गंतव्य फ़ील्ड तक पहुंचता हूं और फ़ाइल में उस बिंदु पर एक और पढ़ा हुआ लूप घोंसला करता हूं। लेकिन मुझे ऐसा करने का एक और उदाहरण नहीं मिला है, इसलिए मुझे लगता है कि मुझे कुछ बुनियादी याद आ रही है या एक बेहतर तरीका है। सहायता के लिए अग्रिम धन्यवाद!

+1

अजगर एक अंतर्निहित में XML पार्सर: http://docs.python.org /library/pyexpat.html –

+3

इनपुट, वांछित आउटपुट, और आपने जो भी प्रयास किया है, +1 के लिए +1। –

+0

आपको संभवतः डेटा निकालने के बाद वाईएएमएल जैसे मानव-अनुकूल सीरियलाइज़र का उपयोग करना चाहिए। आप कभी नहीं जानते कि आपको इस डेटा को फिर से संसाधित करने की आवश्यकता होगी। –

उत्तर

7

lxml जो मैं अत्यधिक अपने डेटा की प्रक्रिया के लिए सिफारिश का उपयोग करने का एक उदाहरण है। (एनबी: Py2.x के लिए लिखा लेकिन 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 

प्रिंटों:

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

कृपया इस तरह की एक्सएमएल फाइलें न पढ़ें, पाइथन के लिए विभिन्न पुस्तकालय हैं जो एक्सएमएल फाइलों को पढ़ने में सहयोग करेंगे।

पायथन लाइब्रेरी lxml पर देखें यह पढ़ने के लिए एक बहुत आसान तरीका प्रदान करता है और फिर एक्सएमएल फाइलों का विश्लेषण करता है और यह आपके कोड को काफी सुधार देगा।

मैं कैसे पुस्तकालय में ही उपयोग करने के लिए की व्याख्या करता है, लेकिन की तुलना में मैं इस पाठ क्षेत्र में निचोड़ कर सकते हैं अपनी दस्तावेज़ीकरण कहीं बेहतर है: http://lxml.de/tutorial.html

+0

धन्यवाद, मैं इसका अध्ययन करूंगा और इसे समझूंगा। तुम्हारी सहायता सराहनीय है। – phlogiston