xmltodictによりXMLをjsonのように処理する【Python】

xmltodictによりXMLをjsonのように処理する【Python】 プログラミング

令和の時代になっても、XMLがダラダラと公開されています。
特に、システム改修がなされない環境ではそうでしょう。

例えば、公的機関の公開するデータです。
また、影響範囲の大きい連携システム(EDIなど)もXMLのままでしょう。

そのXMLは、これまた扱うのが面倒なのですよね。
「jsonのように扱うことができればいいのに」と何度も思ったことです。

それが、xmltodictを使えば簡単に実現できます。

本記事の内容

  • xmltodictとは?
  • xmltodictのシステム要件
  • xmltodictのインストール
  • xmltodictの動作確認

それでは、上記に沿って解説していきましょう。

xmltodictとは?

xmltodictは、Pythonのライブラリです。
名前の通りに、XMLをdict型(辞書型)のデータに変換します。

dict型データであれば、jsonのように処理が可能となります。
地味な機能ですが、何気にプログラミングの生産性を向上できます。

そもそも、XML自体が中途半端な立ち位置です。
ある程度普及したが故に、未だに存在しているという状況です。

そして、まれにXMLを扱うケースに出会います。
その度に、「Python XML」などで調べることになります。

もう、こんなことは終わりにしましょう。
そのためにxmltodictを利用するのです。

XML対応の最終兵器となるxmltodicは、簡単に導入できるのでしょうか?
それを把握するために、xmltodictのシステム要件を確認しましょう。

xmltodictのシステム要件

現時点では、xmltodictの最新バージョンが0.12.0となります。
この最新バージョンが公開されたのは、2019年1月11日です。

更新は、それほど活発ではありませんね。
でも、それだけ完成度が高いのかもしれません。

サポートOSに関しては、以下を含むクロスプラットフォーム対応です。

  • Windows
  • macOS
  • Linux

基本的には、Pythonさえ動けばどこでも動くということですね。
サポート対象となるPythonのバージョンは、少し注意が必要となります。

公式で記載されているバージョンは、以下です。

  • Python 2.7
  • Python 3.4
  • Python 3.5
  • Python 3.6
  • Python 3.7

ここには、Python 3.8と3.9がありません。
でも、安心してください。

これは、更新頻度の低いライブラリあるあるです。
複雑な処理(機械学習絡み)でなければ、大抵は動きます。

実際、私は以下のバージョンで検証しています。

>python -V
Python 3.9.1

問題なくxmltodictを動かすことができています。

以上、xmltodictのシステム要件を説明しました。
次は、xmltodictをインストールしていきましょう。

xmltodictのインストール

最初に、現状のインストール済みパッケージを確認しておきます。

>pip list
Package    Version
---------- -------
pip        21.0.1
setuptools 54.1.1

次にするべきことは、pip自体の更新です。
pipコマンドを使う場合、常に以下のコマンドを実行しておきましょう。

python -m pip install --upgrade pip

では、xmltodictのインストールです。
xmltodictのインストールは、以下のコマンドとなります。

pip install xmltodict

インストールは、すぐに終わります。
では、どんなパッケージがインストールされたのかを確認しましょう。

>pip list
Package    Version
---------- -------
pip        21.0.1
setuptools 54.1.1
xmltodict  0.12.0

xmltodict は、最新バージョンがインストールされています。
依存関係のあるパッケージは、ありません。
そのため、xmltodictを気軽に導入できます。

以上、xmltodict のインストールが完了しました。
次は、xmltodictの動作確認を行いましょう。

xmltodictの動作確認

動作確認をするために、まずはXMLファイルを用意しましょう。

text.xml

<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="http://xml.kishou.go.jp/jmaxml1/" xmlns:jmx="http://xml.kishou.go.jp/jmaxml1/">
  <Control>
    <Title>季節観測</Title>
    <DateTime>2009-01-09T02:02:05Z</DateTime>
    <Status>通常</Status>
     <EditorialOffice>熊谷地方気象台</EditorialOffice>
    <PublishingOffice>熊谷地方気象台</PublishingOffice>
  </Control>
  <Head xmlns="http://xml.kishou.go.jp/jmaxml1/informationBasis1/">
    <Title>季節観測</Title>
    <ReportDateTime>2009-01-09T11:00:00+09:00</ReportDateTime>
    <TargetDateTime>2009-01-09T00:00:00+09:00</TargetDateTime>
    <EventID>20090109110000_初雪</EventID>
    <InfoType>発表</InfoType>
    <Serial />
    <InfoKind>特殊気象報</InfoKind>
    <InfoKindVersion>1.0_0</InfoKindVersion>
    <Headline>
      <Text />
    </Headline>
  </Head>
  <Body xmlns="http://xml.kishou.go.jp/jmaxml1/body/meteorology1/">
    <MeteorologicalInfos type="季節観測">
      <MeteorologicalInfo>
        <DateTime significant="yyyy-mm-dd">2009-01-09T00:00:00+09:00</DateTime>
        <Item>
          <Kind>
            <Name>初雪</Name>
          </Kind>
          <Station>
            <Name>熊谷地方気象台</Name>
            <Code type="国際地点番号">47626</Code>
            <Location>熊谷市桜町</Location>
          </Station>
        </Item>
      </MeteorologicalInfo>
    </MeteorologicalInfos>
   <AdditionalInfo>
      <ObservationAddition>
        <DeviationFromNormal>-9</DeviationFromNormal>
        <DeviationFromLastYear>7</DeviationFromLastYear>
      </ObservationAddition>
    </AdditionalInfo>
  </Body>
</Report>

上記XMLは、気象庁からダウンロードしたモノです。
公的機関では、いまだにXMLでのデータ公開というパターンを目にします。

このXMLをdict型データに変換するコードは、以下。

import xmltodict

# XMLファイルの処理
with open('test.xml', encoding='utf-8') as fp:
    # xml読み込み
    xml_data = fp.read()

    # xml → dict
    dict_data = xmltodict.parse(xml_data)

    print(dict_data)

上記プログラムを実行すると、以下が表示されます。

OrderedDict([('Report', OrderedDict([('@xmlns', 'http://xml.kishou.go.jp/jmaxml1/'), ('@xmlns:jmx', 'http://xml.kishou.go.jp/jmaxml1/'), ('Control', OrderedDict([('Title', '季節観測'), ('DateTime', '2009-01-09T02:02:05Z'), ('Status', '通常'), ('EditorialOffice', '熊谷地方気象台'), ('PublishingOffice', '熊谷地方気象台')])), ('Head', OrderedDict([('@xmlns', 'http://xml.kishou.go.jp/jmaxml1/informationBasis1/'), ('Title', '季節観測'), ('ReportDateTime', '2009-01-09T11:00:00+09:00'), ('TargetDateTime', '2009-01-09T00:00:00+09:00'), ('EventID', '20090109110000_初雪'), ('InfoType', '発表'), ('Serial', None), ('InfoKind', '特殊気象報'), ('InfoKindVersion', '1.0_0'), ('Headline', OrderedDict([('Text', None)]))])), ('Body', OrderedDict([('@xmlns', 'http://xml.kishou.go.jp/jmaxml1/body/meteorology1/'), ('MeteorologicalInfos', OrderedDict([('@type', '季節観測'), ('MeteorologicalInfo', OrderedDict([('DateTime', OrderedDict([('@significant', 'yyyy-mm-dd'), ('#text', '2009-01-09T00:00:00+09:00')])), ('Item', OrderedDict([('Kind', OrderedDict([('Name', '初雪')])), ('Station', OrderedDict([('Name', '熊谷地方気象台'), ('Code', OrderedDict([('@type', '国際地点番号'), ('#text', '47626')])), ('Location', '熊谷市桜町')]))]))]))])), ('AdditionalInfo', OrderedDict([('ObservationAddition', OrderedDict([('DeviationFromNormal', '-9'), ('DeviationFromLastYear', '7')]))]))]))]))])

見事に辞書型になっています。
これでXMLをjsonデータのように扱うことが可能になりました。

以上、xmltodictの動作確認でした。

タイトルとURLをコピーしました