2017-08-03 20 views
0

Pythonで複数のルート要素を持つXMLファイルを解析し、そして私のようなデータを持っているいくつかの使用のために、それから、タグ、いくつかのフェッチする必要があります:私は解析する必要が私はxmlファイルを持っている

<?xml version="1.0"?> 
<data> 
    <country name="Liechtenstein"> 
     <rank>1</rank> 
     <year>2008</year> 
     <gdppc>141100</gdppc> 
     <neighbor name="Austria" direction="E"/> 
     <neighbor name="Switzerland" direction="W"/> 
    </country> 
    <country name="Singapore"> 
     <rank>4</rank> 
     <year>2011</year> 
     <gdppc>59900</gdppc> 
     <neighbor name="Malaysia" direction="N"/> 
    </country> 
    <country name="Panama"> 
     <rank>68</rank> 
     <year>2011</year> 
     <gdppc>13600</gdppc> 
     <neighbor name="Costa Rica" direction="W"/> 
     <neighbor name="Colombia" direction="E"/> 
    </country> 
</data> 
<?xml version="1.0"?> 
<data> 
    <country name="Liechtenstein1"> 
     <rank>1</rank> 
     <year>2008</year> 
     <gdppc>141100</gdppc> 
     <neighbor name="Austria1" direction="E"/> 
     <neighbor name="Switzerland1" direction="W"/> 
    </country> 
    <country name="Singapore"> 
     <rank>4</rank> 
     <year>2011</year> 
     <gdppc>59900</gdppc> 
     <neighbor name="Malaysia1" direction="N"/> 
    </country> 
    <country name="Panama"> 
     <rank>68</rank> 
     <year>2011</year> 
     <gdppc>13600</gdppc> 
     <neighbor name="Costa Rica" direction="W"/> 
     <neighbor name="Colombia" direction="E"/> 
    </country> 
</data> 

をこれは、私が使用:

​​

ライン2でエラーを与えるこのコード:私はこれを解析する方法をxml.etree.ElementTree.ParseError: junk after document element:

私は、複数のXMLタグは、あなたが任意のアイデアを持っているので、これはと思い、?

+1

は "私はxmlファイルを持っている..." いいえ、あなたしないでください。ファイルはどこから来たのですか?その側で問題を修正する可能性はありますか? (それを解析するのはあまり難しいことではありませんが、最初は無効なXMLを避ける方法があればそれが良いでしょう) – smarx

+1

これは有効なXMLファイルではありません。しかし、あなたは '<?xml version =" 1.0 "?>'の前にそれを分割し、パーツを別々に解析することができます。 –

+0

@smarx「可能性はありますか?」とはどういう意味ですか?私はファイルからサンプルデータのみを与えましたが、これにはさらに多くのルート要素が含まれています... @KlausD。より良いオプションを探します。 – ggupta

答えて

1

このコードでは、必要に応じて1つのアプローチの詳細を記入します。

コードは、別のxmlドキュメントの先頭またはファイルの最後に遭遇するまで、 'accumulation_xml'を監視します。完全なxmlドキュメントがある場合はdisplayを呼び出してlxmlライブラリを実行してドキュメントを解析し、内容の一部を報告します。

>>> from lxml import etree 
>>> def display(alist): 
...  tree = etree.fromstring(''.join(alist)) 
...  for country in tree.xpath('.//country'): 
...   print(country.attrib['name'], country.find('rank').text, country.find('year').text) 
...   print([neighbour.attrib['name'] for neighbour in country.xpath('neighbor')]) 
... 
>>> accumulated_xml = [] 
>>> with open('temp.xml') as temp: 
...  while True: 
...   line = temp.readline() 
...   if line: 
...    if line.startswith('<?xml'): 
...     if accumulated_xml: 
...      display (accumulated_xml) 
...      accumulated_xml = [] 
...    else: 
...     accumulated_xml.append(line.strip()) 
...   else: 
...    display (accumulated_xml) 
...    break 
... 
Liechtenstein 1 2008 
['Austria', 'Switzerland'] 
Singapore 4 2011 
['Malaysia'] 
Panama 68 2011 
['Costa Rica', 'Colombia'] 
Liechtenstein1 1 2008 
['Austria1', 'Switzerland1'] 
Singapore 4 2011 
['Malaysia1'] 
Panama 68 2011 
['Costa Rica', 'Colombia'] 
+0

これに感謝、私はちょうど同じアプローチを使用していた、これのためのそのようなPythonライブラリがないのだろうか? – ggupta

+0

ファイルを分割するこの方法を使うときはいつでも、Pythonでそれを表現するより良い方法があるはずです。 –

1

質問:...任意のアイデア、どのように私はこれを解析する必要がありますか?

ファイル全体をフィルタリングし、有効な<?xml ...チャンクに分割します。
myfile_01, myfile_02 ... myfile_nnを作成します。

n = 0 
out_fh = None 
with open('myfile.xml') as in_fh: 
    while True: 
     line = in_fh.readline() 
     if not line: break 

     if line.startswith('<?xml'): 
      if out_fh: 
       out_fh.close() 
      n += 1 
      out_fh = open('myfile_{:02}'.format(n)) 

     out_fh.write(line) 

    out_fh.close() 

あなたがしたい場合は、すべての<country>XML Tree 1中:

import re 
from xml.etree import ElementTree as ET 

with open('myfile.xml') as fh: 
    root = ET.fromstring('<?xml version="1.0"?><data>{}</data>'. 
         format(''.join(re.findall('<country.*?</country>', fh.read(), re.S))) 
           ) 

は、Pythonでテスト:3.4.2

+0

提案のおかげで、同じアプローチを使用しました。ありがとう – ggupta

+0

私はちょうど特定のタグではなく、ファイルを解析する方法を探していた、私の前の答えは、それを変更していただきありがとうございました。 – ggupta

関連する問題