43882


xmlファイルをmongodbへinsertしたいと考えております  
またxmlのデータ型を定義したxsdファイルが別途あるのですが  
このデータ型通りにmongodbへinsertしたいです

現在pythonを利用してxmlファイルを読み取りpythonの辞書型に変更して  
mongodbへのinsertを考えておりますが辞書型にする際にxsdに定義されたデータ型  
に合うように辞書型にする簡単な方法はありますでしょうか？

xmltodict <https://pypi.org/project/xmltodict/>  
というライブラリを利用すると簡単に辞書型に変換してくれるのですが  
データがすべてstr型になります

pythonを必ずしも利用する必要はありませんが、  
比較的得意な言語がpythonです

どうぞ宜しくお願いします


CC BY-SA 3.0
2018-04-23T05:06:31.183
43488
2018-05-09T14:21:22.660
28279
question
python xml mongodb
xmlファイルのmongodbへのinsert


xmltodictを使って辞書型にして、その後で問題があれば修正したらどうでしょうか。

サンプルとしてはこんな感じです。

[code]

    import xmltodict
    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>
    </data>'''
    
    data_dict = xmltodict.parse(xml)
    for country in data_dict['data']['country']:
        country['rank'] = int(country['rank'])
        country['year'] = int(country['year'])
        country['gdppc'] = int(country['gdppc'])
    
[/code]

もし、これで対応できないようであれば、xml.etree.ElementTree
モジュールを使ってXMLデータを解析して、辞書型への変換は自分でした方がいいと思います。


CC BY-SA 3.0
2018-04-26T05:12:10.583
43562
2018-04-26T05:12:10.583
15171
43488
answer


Pythonの [xmlschema](https://github.com/brunato/xmlschema)
というライブラリーを使うと、xsdデータを読み込んで型のチェエクして、数値は int, float
に変換してくれます。日付情報の方は、string型になるような設定になっています、それを修正して日付情報を`date`,`datetime`型で取得するサンプルを書いておきます。

xmlschema/validators/simple_types.py に`datetime`をインポートして

[code]

    from datetime import date, datetime
    
[/code]

の432行目あたりを以下のように変更してdate型及びdatetime型に変換するコードを追加します。

[code]

    if self.prefixed_name == 'xs:date':
        try:
            ts = _text.split('-')
            yield date(int(ts[0]), int(ts[1]), int(ts[2]))
        except (ValueError, IndexError) as err:
            # エラー処理
            yield None
        return
    if self.prefixed_name == 'xs:datetime':
        try:
            yield datetime.strptime(_text, '%Y-%m-%dT%H:%M:%S')
        except ValueError as err:
            # エラー処理
            yield None
        return            
    # 以下のコードの前におく
    try:
        result = self.to_python(_text)
    except (ValueError, DecimalException) as err:
    .....
    
[/code]

ソースコードに手を入れるのであれば、`xmltodict`の方でも同じようにできます。自分でキーの型情報を作成する必要がありあますが、普通は
`string` 以外に int, float, date, datetime
ぐらいしか出てこないので、`xmltodict`を使った方がコードがシンプルなだけに楽に処理できるケースが多いと思います。


CC BY-SA 4.0
2018-05-09T04:18:46.153
43882
2018-05-09T14:21:22.660
2018-05-09T14:21:22.660
15171
15171
43488
answer