[nim]XMLをパース(parse)する

広告

nimを使ってXMLファイルをパースする為の日本語情報があまりないので、「xmlparser」モジュールを使ってのXMLファイルのパースについて記事にします
色々苦労しましたが、なんとか思い通りの動きができるようになりました

xmlparserモジュールの仕様

以下のリンクにて説明があります(英語)
XMLParserの仕様

使用例
といっても、所詮英語…一応以下のような仕様です

xmlをロードする

XmlParserがFileStreamをオ−プンしています

ノードを読み込む

xmlparserは、nextで次のノードに移ります
ループさせて、EOFまで読み込みます
xp.kindによって処理を分岐させる形になります

上記の例だと、EOF(xmlEof)まで無限ループを回して、xmlEofを見つけたら、ブレイクするという流れになります

kindは、以下のようなものがあります。よく使うものから順に紹介すると以下の通り

kindの名前 内容
xmlElementStart XMLの構成要素の開始を示します(”>”までを取得

 < elem >
xmlElementEnd XMLの構成要素の終了そ示す(”>”までを取得

 < /elem >
xmlElementOpen XMLの構成要素の開始を示す(”>”までを取得しない

 < /elem
xmlElementClose Openで取得した構成要素の”>”を取得する

 >
xmlAttribute Openで取得した構成要素の中にあるアトリビュートを取得

 key=”value”
xmlCharData 文字列データ

 テキスト
xmlError エラーが起きたときの

N/A
xmlEOF ファイルの終了

N/A

詳細は、以下の英語の説明にあるのですが、とりあえず上記さえあれば、なんとかコントロールできます

xmlElementStartとxmlElementOpenの違い

実は、最初この2つの使い方が理解できなかったのですが、基本的には以下のような違いのようです
例えば、以下のようなXMLファイルがあったとします

この場合に、kind==xmlElementStartで得られた構成要素の名前(elementName)を抽出すると以下のように取れます

取得するソースは、以下の通り

上記のソースコードで実行結果は、以下のようになります

見ていただくと気づきますが、showは、抽出されていません。これは、showはアトリビュート「id」を保有しているためです

アトリビュートを保有する項目は、「xmlElementOpen」で分岐する必要があります

上記のコードを以下のように修正して実行します

上記のコードの実行結果は以下のとおりです

この通り、この「xmlElementOpen」と「xmlElementStart」を両方キャッチしないとXMLの構成要素を全て取得することができません

要素のテキストを取得するのは、kindがCharDataであるときに取得する

上記のように、要素を特定したあとは、その要素の内容を取得します

上記のコマンドの組み合わせで、取り込めるようになりました

以上 nimでXMLファイルをパースして情報を取り込むための初歩の記事でした

PSちなみに、同様の処理をRubyとnimで実装した場合の速度比較は以下

3248のXMLファイルのパース処理

Ruby:18分4秒(4320秒)

nim :13秒

という圧倒的な差。332倍のスピード!!

ま、完全に同じ処理というわけではないのですが、それにして圧倒的です

広告

1 個のコメント

  • どうでもいいけど、「パース」じゃなくて「パーズ」ですよね。

  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です