pythonに標準で入ってるXMLを扱えるモジュールElementTreeを使ってみました。
この記事ではElementTreeを使ってXMLではなくAIMLをパースしてプログラム内で利用しやすい形に変換してみます。
関連リンク
20.5. xml.etree.ElementTree — ElementTree XML API — Python 3.6.5 ドキュメント
AIML Tutorial
AIML
AIMLとはArtificial Intelligence Markup Languageの略でXMLベースのマークアップ言語です。Artificial Linguistic Internet Computer Entity (A.L.I.C.E.) と呼ばれるチャットボットの開発の際に作られました。(※AIMLについての詳細な説明は今回は省略します。)
AIMLの中身は以下のような感じです。このようなAIML形式のファイルをElementTreeを使って解析したいと思います。
<aiml>
<category>
<pattern>こんにちは</pattern>
<template>こんにちはー</template>
</category>
<category>
<pattern>おはよう</pattern>
<template>おっはー</template>
</category>
</aiml>
ElementTreeを使ってデータを読み込む
上にあるファイルを解析するファイルとして使います。ファイルの名前をsample.aiml
とします。
モジュールのインポート
まずは必要なモジュールをインポートします。
import xml.etree.ElementTree as ET
ファイルを読み込む
parse()
からAIMLファイルを読み込みます。
fname = "sample.aiml"
document = ET.parse(fname)
categories = document.findall("./category")
続いてfindall()
を使って<category></category>で囲まれた部分を取得します。
categoryの中身を見る。
先ほど取得したcategoriesはリストになっていて、その中身は<category></category>で囲まれている要素が入っています。
以下のコードではcategoryの要素であるpatternとtemplateのテキストを取り出しています。
for category in categories:
pattern = category.find('pattern').text
template = category.find('template').text
print(pattern)
print(template)
print()
find()
を使ってcategoryの中から指定したタグを見つけたらそれをテキスト形式にしています。
こんにちは
こんにちはー
おはよう
おっはー
AIMLファイルを作る
ElementTreeを使ってAIML形式のファイルを作ってみます。
AIMLファイルを作る
fromstring()
を使って文字列からElementを生成します。このとき作られたElementはパースされた木のルート要素になります。つまり、parse()
を使ってAIMLファイルを読み込んだときと同じ状態になっています。
import xml.etree.ElementTree as ET
aiml = ET.fromstring("<aiml>\n</aiml>")
aiml
に新しい要素を追加してみます。追加する要素はElementクラスのオブジェクトでなければなりません。文字列を直接追加しようとするとエラーがでます。
今回は例としてsample.aiml
のpattern要素の文字列の長さが5以上のものをaiml
に加えてみます。
fname = "sample.aiml"
document = ET.parse(fname)
for category in document.findall("./category"):
pattern = category.find("pattern").text
if len(pattern) >= 5:
aiml.append(category)
aiml
をファイルとして保存するには、新しくElementTreeを生成した上でwrite()
で中身をファイルに書き込みます。
aiml_file = ET.ElementTree(aiml)
aiml_file.write('new_sample.aiml', encoding='utf-8')
生成されたファイル
<aiml>
<category>
<pattern>こんにちは</pattern>
<template>こんにちはー</template>
</category>
</aiml>
データを読み込む
import xml.etree.ElementTree as ET
fname = "sample.aiml"
document = ET.parse(fname)
categories = document.findall("./category")
for category in categories:
pattern = category.find('pattern').text
template = category.find('template').text
print(pattern)
print(template)
print()
データを書き込む
import xml.etree.ElementTree as ET
aiml = ET.fromstring("<aiml>\n</aiml>")
fname = "sample.aiml"
document = ET.parse(fname)
for category in document.findall("./category"):
pattern = category.find("pattern").text
if len(pattern) >= 5:
aiml.append(category)
aiml_file = ET.ElementTree(aiml)
aiml_file.write('new_sample.aiml', encoding='utf-8')