tkxml.py ライブラリ技術ドキュメント

ライブラリの機能や目的

tkxml.py は、XMLデータとPythonの辞書構造間の変換、およびXMLファイルからの特定の情報抽出を容易にするためのユーティリティライブラリです。主に、科学技術計算に関連する複雑なXMLファイル(例: ATLAS最適化XML、VASPのvasprun.xml)の解析を目的としており、以下の課題を解決します。

  • XMLとPython辞書の相互変換: 複雑なXML構造をPythonの辞書に変換することで、プログラミングによるデータ操作を簡素化します。また、辞書からXMLを生成することも可能です。

  • 特定のXMLセクションの抽出: XPathライクなタグパス指定により、XMLツリー内の特定のセクション(要素のグループや属性)を効率的に抽出し、構造化されたPythonデータとして取得します。

  • XMLの読み書きと整形: XMLファイルを読み込み、Pythonのxml.etree.ElementTreeオブジェクトとして扱ったり、整形してファイルに書き出したりする機能を提供します。

このライブラリは、XMLデータをよりプログラマティックに扱いやすくし、特に特定のフォーマットを持つXMLファイルからのデータ抽出や加工のプロセスを自動化するのに役立ちます。

importする方法

tkxml.py ライブラリを他のPythonプログラムから利用するには、通常のモジュールと同様に import ステートメントを使用します。

import tkxml

# tkxml.py 内の関数や変数にアクセス
root_element = tkxml.get_root("path/to/your/file.xml")

特定の関数のみをインポートすることも可能です。

from tkxml import file2dict, dict2xml

data_dict = file2dict("path/to/your/file.xml")
xml_element = dict2xml(data_dict)

必要な非標準ライブラリとインストール方法

tkxml.py は、XMLと辞書の変換に特化した外部ライブラリに依存しています。これらは pip コマンドでインストールできます。

  • xmltodict: XMLドキュメントをPython辞書に変換するために使用されます。

  • dicttoxml: Python辞書をXMLドキュメントに変換するために使用されます。

  • numpy: 数値計算ライブラリとしてインポートされていますが、このソースコード内では直接的な利用箇所が見られません。一部の環境での依存関係や、将来的な利用を想定している可能性があります。

これらのライブラリは、以下のコマンドでインストールできます。

pip install xmltodict dicttoxml numpy

importできる変数と関数

グローバル変数

  • infile (str):

    • デフォルトの入力XMLファイルパス。スクリプトが直接実行された際に、コマンドライン引数がない場合にこの値が使用されます。初期値は 'opt_2onl.xml' です。

関数

get_elements_recursive(element)

XML要素の子要素を再帰的に走査し、その情報を抽出します。

  • 動作: 入力されたelementに子要素がない場合はそのテキスト内容を返します。子要素がある場合は、各子要素のタグ、テキスト、属性、およびその子要素の再帰的な情報を辞書のリストとして返します。

  • 引数:

    • element (xml.etree.ElementTree.Element): 処理対象のXML要素インスタンス。

  • 戻り値:

    • str: 要素が子要素を持たない場合、そのテキスト内容。

    • list[dict]: 要素が子要素を持つ場合、子要素の情報を格納した辞書のリスト。各辞書は"tag", "text", "attrib"、および子要素を持つ場合は"child"キーを含みます。

get_unique_key(d, section, val = None)

指定されたsectionvalに基づいて、辞書d内でユニークなキーを生成します。

  • 動作: sectionvalからキーを生成し、そのキーが辞書dに既に存在しない場合はそのキーを返します。存在する場合は、section[i]またはsection[i]:valの形式でインデックスiを付加し、ユニークなキーが見つかるまでiをインクリメントします。

  • 引数:

    • d (dict): キーの重複を確認する対象の辞書。

    • section (str): キーのベースとなるセクション名。

    • val (str, None): オプションのキーの値を指定する。デフォルトはNone

  • 戻り値:

    • str: 辞書d内でユニークなキー。

get_section_inf(parent, sections = None, inf = None, params = None, ret_type = 'list', add_parent_params = True)

XMLツリー内の特定のセクション(タグパスで指定)の情報を取得します。

  • 動作: parent要素からsectionsで指定されたタグパスを辿り、最後のセクションの子要素の情報を抽出します。抽出された情報はret_typeに基づいてリストまたは辞書として整形されます。add_parent_paramsTrueの場合、親要素の属性情報も追加されます。

  • 引数:

    • parent (xml.etree.ElementTree.Element): 検索を開始する親XML要素。

    • sections (list[str], None): 検索するタグ名のリスト。例: ['parameter-list', 'parameter']。デフォルトはNone

    • inf (list or dict, None): 既存の情報に追加する場合に指定。デフォルトはNone

    • params (dict, None): 既存のパラメータ情報に追加する場合に指定。デフォルトはNone

    • ret_type (str): 戻り値の型を指定 ('list'または'dict')。デフォルトは'list'

    • add_parent_params (bool): 親要素の属性情報を結果に追加するかどうか。デフォルトはTrue

  • 戻り値:

    • list or dict: 抽出された情報。ret_type'list'の場合は辞書のリスト、'dict'の場合はキーが最後のセクションの属性値(または'list')となる辞書。

get_section_inf_all(parent, sections = None, section_parent = 'root', inf = None, level = 0, params = None, pkey = None, ret_type = 'list', last_node_only = True)

XMLツリー内の特定のセクションパスを再帰的に走査し、一致する全ての要素の情報を取得します。get_section_infよりも汎用的な情報抽出を目的としています。

  • 動作: parent要素からsectionsのタグパスを再帰的に辿り、パス内の各レベルで一致する要素の情報を抽出します。last_node_onlyTrueの場合、パスの最後のノードのみを結果に含めます。levelparamsは再帰の階層と親の属性を保持します。

  • 引数:

    • parent (xml.etree.ElementTree.Element): 検索を開始する親XML要素。

    • sections (list[str], None): 検索するタグ名のリスト。例: ['parameter-list', 'parameter']。デフォルトはNone

    • section_parent (str): 現在のparentのタグ名。内部的な再帰処理で使用。デフォルトは'root'

    • inf (list or dict, None): 既存の情報に追加する場合に指定。デフォルトはNone

    • level (int): 現在の処理レベル(深さ)。内部的な再帰処理で使用。デフォルトは0

    • params (dict, None): 現在の要素に継承される親要素の属性の辞書。デフォルトはNone

    • pkey (str, None): ret_type'dict'の場合にキーとして使用する属性名。デフォルトはNone

    • ret_type (str): 戻り値の型を指定 ('list'または'dict')。デフォルトは'list'

    • last_node_only (bool): Trueの場合、sectionsパスの最後の要素のみを結果に含める。Falseの場合、パス上の全ての要素を含める。デフォルトはTrue

  • 戻り値:

    • list or dict: 抽出された情報。各要素は"level", "tag", "text", "attrib", "params"キーを持つ辞書です。

xml2dict(xml)

XMLインスタンスまたはXML文字列をPython辞書に変換します。

  • 動作: 内部でxmltodict.parse()を使用し、入力されたXMLデータをPython辞書構造に変換します。

  • 引数:

    • xml (str or xml.etree.ElementTree.Element): XML文字列、またはxml.etree.ElementTree.Elementインスタンス。

  • 戻り値:

    • dict: 変換されたPython辞書。

_element_to_dict(element)

xml.etree.ElementTree.Elementオブジェクトを再帰的に辞書に変換する内部ヘルパー関数です。

  • 動作: 要素の属性は'@attributes'キーの下に、テキスト内容は'#text'キーの下に格納されます。同じタグ名の子要素が複数ある場合はリストとして扱われます。この関数は、xml2dictxmltodictを使用する代替として、または標準ライブラリのみでXML-Dict変換を行うための内部実装として存在します。

  • 引数:

    • element (xml.etree.ElementTree.Element): 変換するXML要素。

  • 戻り値:

    • dict: 変換されたPython辞書。

file2dict(infile)

指定されたファイルパスのXMLファイルを読み込み、その内容をPython辞書に変換します。

  • 動作: ファイルを読み込み、その内容をxml2dict関数に渡して辞書に変換します。

  • 引数:

    • infile (str): 入力XMLファイルのパス。

  • 戻り値:

    • dict: 変換されたPython辞書。

dict2xml(d, attr_type = True, root = True)

Python辞書をXMLインスタンスに変換します。

  • 動作: 内部でdicttoxml.dicttoxml()を使用し、入力されたPython辞書をXMLインスタンスに変換します。

  • 引数:

    • d (dict): 変換するPython辞書。

    • attr_type (bool): 属性の型を考慮するかどうか。dicttoxmlの引数に準拠。デフォルトはTrue

    • root (bool): ルート要素を生成するかどうか。dicttoxmlの引数に準拠。デフォルトはTrue

  • 戻り値:

    • bytes: 変換されたXMLインスタンス(バイト列)。

to_xml(outfile, element, encoding = 'utf-8', newl = '', indent = '', addindent = '    ', xml_declaration = True, use_minidom = False)

XML要素をファイルに書き出します。必要に応じてxml.dom.minidomを使用してXMLを整形できます。

  • 動作: elementoutfileに書き込みます。use_minidomTrueの場合、xml.dom.minidomを使用してXMLを整形(インデントや改行を追加)してから書き込みます。xml_declarationフラグでXML宣言の有無を制御します。

  • 引数:

    • outfile (str): 書き込み先のファイルパス。

    • element (xml.etree.ElementTree.Element): 書き込むルートXML要素。

    • encoding (str): 出力ファイルのエンコーディング。デフォルトは'utf-8'

    • newl (str): use_minidom=Trueの場合の改行文字。デフォルトは''

    • indent (str): use_minidom=Trueの場合の最初のインデント文字。デフォルトは''

    • addindent (str): use_minidom=Trueの場合の各レベルの追加インデント文字。デフォルトは'    '

    • xml_declaration (bool): XML宣言をファイルに含めるかどうか。デフォルトはTrue

    • use_minidom (bool): xml.dom.minidomを使ってXMLを整形するかどうか。デフォルトはFalse

  • 戻り値:

    • None

get_attrib(element)

XML要素のタグ名、テキスト内容、および属性を抽出します。

  • 動作: 入力されたXML要素のtagtextattribプロパティを返します。

  • 引数:

    • element (xml.etree.ElementTree.Element): 情報を取得するXML要素インスタンス。

  • 戻り値:

    • tuple[str, str, dict]: 要素のタグ名、テキスト内容、属性の辞書を順に格納したタプル。

get_root(xml)

XMLソースからXMLのルート要素を取得します。

  • 動作: xml引数がファイルパスである場合はファイルを解析し、文字列である場合は文字列を解析して、XMLツリーのルート要素を返します。

  • 引数:

    • xml (str): XMLファイルパスまたはXMLデータを含む文字列。

  • 戻り値:

    • xml.etree.ElementTree.Element: XMLツリーのルート要素。

main scriptとして実行したときの動作

tkxml.py がPythonスクリプトとして直接実行された場合(python tkxml.py)、main() 関数が呼び出されます。この main() 関数は以下の動作を実行します。

  1. 入力ファイルの決定:

    • コマンドライン引数が指定されている場合(例: python tkxml.py your_file.xml)、最初の引数 (sys.argv[1]) を入力ファイルパス (infile) として使用します。

    • コマンドライン引数がない場合、グローバル変数 infile のデフォルト値('opt_2onl.xml')を使用します。

  2. XMLファイルのロード:

    • 決定された入力ファイルパスから get_root() 関数を使用してXMLのルート要素を読み込みます。

  3. XMLタイプの判別と情報抽出:

    • 読み込んだXMLルート要素に対して、特定のXPath (.//parameter-list または .//incar) を使ってXMLの種類を判別します。

    • ATLAS最適化XMLと判断された場合 (.//parameter-list が見つかる場合):

      • parameter-listsettingstarget-list セクションから、それぞれ parametersettingtarget 要素の情報を get_section_inf_all() 関数を使って辞書形式で抽出します。

      • 抽出された parameter_infsetting_inftarget_inf の内容を標準出力に表示します。

    • VASPのvasprun.xmlと判断された場合 (.//incar が見つかる場合):

      • projected_kpoints_opteigenvaluesset[@comment]r など、バンド情報に関連するセクションからデータを get_section_inf_all() 関数を使って抽出します。

      • incar セクションから、その子要素の情報を get_section_inf_all() 関数を使って辞書形式で抽出します(pkey='name'でキーを生成)。

      • 抽出された band_infincar_inf の内容を標準出力に表示します。

    • 上記以外のXMLタイプの場合:

      • "Error: Invalid XML type" というメッセージを標準出力に表示し、プログラムを終了します。

この main() 関数は、ライブラリの様々な情報抽出機能のデモンストレーションとして機能し、特定のXMLフォーマットからのデータ解析の具体的な例を示しています。