2017-05-05 8 views
1

私は非常にPythonの新版です。私はこの非常に大きなxmlファイルを持っており、そこからいくつかのデータを抽出したいと思います。ここでは抜粋です:私がやりたい何多くの子供と孫がいるXMLファイルの解析

<program> 
    <id>38e072a7-8fc9-4f9a-8eac-3957905c0002</id> 
    <programID>3853</programID> 
    <orchestra>New York Philharmonic</orchestra> 
    <season>1842-43</season> 
    <concertInfo> 
     <eventType>Subscription Season</eventType> 
     <Location>Manhattan, NY</Location> 
     <Venue>Apollo Rooms</Venue> 
     <Date>1842-12-07T05:00:00Z</Date> 
     <Time>8:00PM</Time> 
    </concertInfo> 
    <worksInfo> 
     <work ID="52446*"> 
      <composerName>Beethoven, Ludwig van</composerName> 
      <workTitle>SYMPHONY NO. 5 IN C MINOR, OP.67</workTitle> 
      <conductorName>Hill, Ureli Corelli</conductorName> 
     </work> 
     <work ID="8834*4"> 
      <composerName>Weber, Carl Maria Von</composerName> 
      <workTitle>OBERON</workTitle> 
      <movement>"Ozean, du Ungeheuer" (Ocean, thou mighty monster), Reiza (Scene and Aria), Act II</movement> 
      <conductorName>Timm, Henry C.</conductorName> 
      <soloists> 
       <soloist> 
        <soloistName>Otto, Antoinette</soloistName> 
        <soloistInstrument>Soprano</soloistInstrument> 
        <soloistRoles>S</soloistRoles> 
       </soloist> 
      </soloists> 
     </work> 
     <work ID="3642*"> 
      <composerName>Hummel, Johann</composerName> 
      <workTitle>QUINTET, PIANO, D MINOR, OP. 74</workTitle> 
      <soloists> 
       <soloist> 
        <soloistName>Scharfenberg, William</soloistName> 
        <soloistInstrument>Piano</soloistInstrument> 
        <soloistRoles>A</soloistRoles> 
       </soloist> 
       <soloist> 
        <soloistName>Hill, Ureli Corelli</soloistName> 
        <soloistInstrument>Violin</soloistInstrument> 
        <soloistRoles>A</soloistRoles> 
       </soloist> 
       <soloist> 
        <soloistName>Derwort, G. H.</soloistName> 
        <soloistInstrument>Viola</soloistInstrument> 
        <soloistRoles>A</soloistRoles> 
       </soloist> 
       <soloist> 
        <soloistName>Boucher, Alfred</soloistName> 
        <soloistInstrument>Cello</soloistInstrument> 
        <soloistRoles>A</soloistRoles> 
       </soloist> 
       <soloist> 
        <soloistName>Rosier, F. W.</soloistName> 
        <soloistInstrument>Contrabass</soloistInstrument> 
        <soloistRoles>A</soloistRoles> 
       </soloist> 
      </soloists> 
     </work> 
     <work ID="0*"> 
      <interval>Intermission</interval> 
     </work> 
     <work ID="8834*3"> 
      <composerName>Weber, Carl Maria Von</composerName> 
      <workTitle>OBERON</workTitle> 
      <movement>Overture</movement> 
      <conductorName>Etienne, Denis G.</conductorName> 
     </work> 
     <work ID="8835*1"> 
      <composerName>Rossini, Gioachino</composerName> 
      <workTitle>ARMIDA</workTitle> 
      <movement>Duet</movement> 
      <conductorName>Timm, Henry C.</conductorName> 
      <soloists> 
       <soloist> 
        <soloistName>Otto, Antoinette</soloistName> 
        <soloistInstrument>Soprano</soloistInstrument> 
        <soloistRoles>S</soloistRoles> 
       </soloist> 
       <soloist> 
        <soloistName>Horn, Charles Edward</soloistName> 
        <soloistInstrument>Tenor</soloistInstrument> 
        <soloistRoles>S</soloistRoles> 
       </soloist> 
      </soloists> 
     </work> 
     <work ID="8837*6"> 
      <composerName>Beethoven, Ludwig van</composerName> 
      <workTitle>FIDELIO, OP. 72</workTitle> 
      <movement>"In Des Lebens Fruhlingstagen...O spur ich nicht linde," Florestan (aria)</movement> 
      <conductorName>Timm, Henry C.</conductorName> 
      <soloists> 
       <soloist> 
        <soloistName>Horn, Charles Edward</soloistName> 
        <soloistInstrument>Tenor</soloistInstrument> 
        <soloistRoles>S</soloistRoles> 
       </soloist> 
      </soloists> 
     </work> 
     <work ID="8336*4"> 
      <composerName>Mozart, Wolfgang Amadeus</composerName> 
      <workTitle>ABDUCTION FROM THE SERAGLIO,THE, K.384</workTitle> 
      <movement>"Ach Ich liebte," Konstanze (aria)</movement> 
      <conductorName>Timm, Henry C.</conductorName> 
      <soloists> 
       <soloist> 
        <soloistName>Otto, Antoinette</soloistName> 
        <soloistInstrument>Soprano</soloistInstrument> 
        <soloistRoles>S</soloistRoles> 
       </soloist> 
      </soloists> 
     </work> 
     <work ID="5543*"> 
      <composerName>Kalliwoda, Johann W.</composerName> 
      <workTitle>OVERTURE NO. 1, D MINOR, OP. 38</workTitle> 
      <conductorName>Timm, Henry C.</conductorName> 
     </work> 
    </worksInfo> 
</program> 
<program> 

は、以下の情報を抽出している:プログラムID、オーケストラ、季節、eventTypeを、作業ID、soloistName、solositInstrument、soloistRole

は、ここでは、コードです私が使用しています:

import csv 
import xml.etree.cElementTree as ET 
tree = ET.iterparse('complete.xml.txt') 
#root = tree.getroot() 


for program in root.iter('program'): 
    ID = program.findtext('id') 
    programID = program.findtext('programID') 
    orchestra = program.findtext('orchestra') 
    season = program.findtext('season') 

    for concert in program.findall('concertInfo'): 
    event = concert.findtext('eventType') 

    for worksInfo in program.findall('worksInfo'): 
     for work in worksInfo.iter('work'): 
      workid = work.get('ID') 
      for soloists in work.iter('soloists'): 
       for soloist in soloists.iter('soloist'): 
        soloname = soloist.findtext('soloistName') 
        soloinstrument =                `soloist.findtext('soloistInstrument')` 
        solorole = soloist.findtext('soloistRoles') 
        #print(soloname, soloinstrument, solorole) 
      #print(workid) 
    #print(event)    
#print(programID , " , " , orchestra , " , " , season) 
with open("nyphil.txt","a") as nyphil: 
    nyphilwriter = csv.writer(nyphil) 
    nyphilwriter.writerow([programID, orchestra, season, event, workid, `soloname.encode('utf-8'), soloinstrument, solorole]) 
nyphil.close() 

私はこのコードを実行すると、私は最後のsoloistNameとsoloistInstrumetを取得します。私が考えている結果は、各プログラムの繰り返し観測のようなものです。

13918、ニューヨーク・フィル、1842年から1843年、サブスクリプションの季節、52446 *、オットー、アントワネット、ソプラノ、S

13918、...、3642 *、Scharfenberg:だから私のようなものを持っていると思いますその上、ウィリアム、ピアノ、

13918、...、3642 *、ヒル、Ureliコレッリ、ヴァイオリン、

と最後の作品のIDまで:

13918、... 、8336 * 4、Otto、Antoinette、Soprano、S

私は取得しています何

は唯一の最後の作品である:

13918、ニューヨーク・フィル、1842年から1843年、サブスクリプションのシーズン、8336 *、オットー、アントワネット、ソプラノ、S

ファイルでは15,000の上にあります私が掲示した例のようなプログラム。私はそれらのすべてを解析し、上記の情報を抽出したいと思います。私はこれを行う方法については完全にはわかりません、私はこれを行う方法のためにインターネットを洗ったが、私が試したすべてがうまくいきません!!

答えて

0

ここで問題となるのは、ループが動作する方法を誤解していることです。

for x in range(10): 
    print(x) 

これら2つの異なるものですVS

for x in range(10): 
    pass 

print(x) # prints 9 

:あなたがループにいる間具体的には、値のみが変更されます。あなたは前者をやっている。あなたがする必要があるのは次のようなものです:

with open('nyphil.txt', 'w') as f: 
    nyphilwriter = csv.writer(f)   
    for program in root.iter('program'): 
     id_ = program.findtext('id') 
     program_id = program.findtext('programID') 
     orchestra = program.findtext('orchestra') 
     season = program.findtext('season') 
     for concert in program.findall('concertInfo'): 
      event = concert.findtext('eventType') 
     for info in program.findall('worksInfo'): 
      for work in info.iter('work'): 
       work_id = work.get('ID') 
       for soloists in work.iter('soloists'): 
        for soloist in soloists.iter('soloist'): 
         # Change this line to whatever you want to write out 
         nyphilwriter.writerow([id, program_id, orchestra, season, event, work_id, soloist.findtext('soloistName')]) 
+0

ありがとうございました!これはまさに私が必要としていたものです。私はこれのすべてに非常に新しいです、そして、私は実際ループが実際に働く方法で本当に混乱しました。これは非常に助けになりました、ありがとう!! –

+0

この回答があなたの問題を最もよく解決するものであれば、左側のチェックマークを押して「OK」を選択してください。特に役立つ情報がある場合は、その数字の上にある三角形でアップボートすることもできます。 –

+0

こんにちはウェイン、私はそれをupvotedしかし、私は記録されていないように15未満の評判を持っている:/あなたの答えは非常に役立った! –

0

13918はあなたのデータには現れません。それを残して、ここに私が書いたものがあります。あなたのデータをうまく処理しているようです。

from lxml import etree 

tree = etree.parse('test.xml') 
programs = tree.xpath('.//program') 

for program in programs: 
    programID, orchestra, season = [program.xpath(_)[0].text for _ in ['programID', 'orchestra', 'season']] 
    print (programID, orchestra, season) 
    works = program.xpath('worksInfo/work') 
    for work in works: 
     workID = work.attrib['ID'] 
     soloistItems = work.xpath('soloists/soloist') 
     for soloistItem in soloistItems: 
      print (workID, soloistItem.find('soloistName').text, soloistItem.find('soloistInstrument').text, soloistItem.find('soloistRoles').text) 

スクリプトは次の出力を生成します。

3853 New York Philharmonic 1842-43 
8834*4 Otto, Antoinette Soprano S 
3642* Scharfenberg, William Piano A 
3642* Hill, Ureli Corelli Violin A 
3642* Derwort, G. H. Viola A 
3642* Boucher, Alfred Cello A 
3642* Rosier, F. W. Contrabass A 
8835*1 Otto, Antoinette Soprano S 
8835*1 Horn, Charles Edward Tenor S 
8837*6 Horn, Charles Edward Tenor S 
8336*4 Otto, Antoinette Soprano S 

もう一つの事は注意する:実際のデータは複数の要素が含まれますので、私は最後にあなたのXMLの始まりとでタグを置きます。

関連する問題