XML文書からXPathで要素を抜き出すCLIツールを作った

この記事はRuby Advent Calendar 2019 10日目の記事です。

久しぶりにアドベントカレンダーにエントリーしたので、最近作ってみたいと思った地味なgemを作りました。

TL;DR

作ったものはこちらです。

github.com

しかしながらRubygems.orgのMFAで詰まってしまっていて、まだリリースできていません。 もし使う場合は、上のリポジトリをcloneしてgemファイルをビルドし、インストールする必要があります。

動機

お仕事でXMLドキュメントを解析しながらそれを処理する必要がありました。 複雑なXMLドキュメントで、スキーマもいまいちわからないものだったので、いきなりコードを書くよりも、必要な情報を抜き出すためのXPathはどんなものだろうかというのを試行錯誤するところからはじめました。

XMLパーサーといえばNokogiriと思い、nokogiriに同梱されているcliを使ってみました。 これはこれで便利で、指定したドキュメントを@docに読み込んだ状態でirbが起動されます。 便利なのですが、XPathで抜き出した要素が大量に出てくる時の表示が面倒だったり、結果をファイルに保存する時にいちいちFileを操作しないといけないのが煩わしいと思いました。

そこで、解析したいXMLドキュメントとXPathを指定することで、XPathにマッチする要素を出力するだけのコマンドラインツールを作ることにしました。

使い方

READMEに記載していますが、シンプルにXML文書のファイルパスもしくはURIXPathを指定することで実行できます。

kamikiri --file /path/to/xml/file.xml --xpath '//foo/bar'
kamikiri --file /path/to/xml/file.xml --xpath '//foo/bar'

例えば、下記のように、CDのカタログから1980年代の10ドルより高いCDを抜き出すことができます。

$ kamikiri --file https://www.w3schools.com/xml/cd_catalog.xml --xpath '//CD[PRICE > 10.0][YEAR > 1990]'
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>

パイプやリダイレクトと組み合わせれば、ファイルに保存したり一部の文字列を書き換えたりとか幅広く使えそうです。CLI、便利。

おまけ

ある程度形になって実行できるようになったのでrubygems.orgにgemファイルをpushしようとしたのですが、MFAのOTPコードを入手する手段を失ってしまいました。 以前にMFAの設定した時に登録したデバイスiPhone)から今のデバイスに乗り換えた時に、登録していたAuthenticatorをアンインストールしてしまったためです。 MFA LevelをUIとAPIの両方に設定していたので、rubygems.orgのウェブ画面からログインする際にもOTPコードを求められてしまう状態です。

サインイン画面から確認メールを再送することで、ログイン状態にすることはできたのですが、ドキュメントにあるようにプロフィール編集画面にQRコードが出てこない状態です。

Setting up multi-factor authentication - RubyGems Guides

という状態のため、今回作ったgemをまだリリースできないままでいます。 誰か助けて。