組み込みのXPath関数を使用する

以下に、あるものを開発するにあたって、 Altova オンライン研修プログラム コースのデータにおいて、書籍を著者名で並べ替える際に、著者名がフルネームの文字列として扱われていることに気づきました。そのため、書籍は文字列の最初の文字、つまり著者の姓で並べ替えられていました。この並び順を修正することは、今回のコースの範囲外でしたが、XPath関数を使用することで、文字列から姓を簡単に抽出して、並べ替えのキーとして利用することができます。次に、書籍のタイトルを二次的な並べ替えキーとして使用しようとすると、「A」、「An」、または「The」で始まるタイトルが問題となります。私は、タイトルを二次的な並べ替えキーとして使用したいのですが、先頭の定冠詞や不定冠詞は無視したいと考えています。

このXSLTコードがどのように作成されたのか、見ていきましょう。この記事は、XMLSpyをプラットフォームとして使用して作成されましたが、同じXPath式をMapForceStyleVision内でも使用することで、同様の結果を得ることができます。まずは、シンプルなXML形式の書籍リストから始めましょう。ここでは、著者名とタイトルを持つ4つの書籍データを用意します。

XSLTを使って書籍のリストを作成する場合、以下のようなコードになります

これにより、以下の結果が出力されます

これらの書籍は、元のデータファイルに記載されている順序で出力されます。もし、xsl:for-eachループにxsl:sortを追加すれば、出力の順序を他の方法で調整することができます。

これにより、ソートされたリストが生成されますが、完全に正しくソートされているわけではありません。

著者を文字列としてソートすると、「ジュール・ヴェルヌ」が「マーク・トウェイン」の前に表示されます。また、「アーサー王の宮廷に現れたコネチカット人」が「ハックルベリー・フィンの冒険」の前に表示されます。私たちは、不定冠詞「A」を無視して、「ハックルベリー・フィンの冒険」を「アーサー王の宮廷に現れたコネチカット人」の前に表示したいと考えています。XPath式を使用して、必要なソートキーを抽出することができます。

コードの出力を見てみる前に、まずコードを詳しく見ていきましょう。ここでは、「author」を「reverse(tokenize(author, ' '))[1]」に置き換えています。tokenize関数は、指定された区切り文字(ここでは単一の空白)を使って、文字列をトークンに分割します。したがって、「Jules Verne」は「Jules」と「Verne」に分割されます。reverse関数は、トークンの順番を逆にして「Verne」と「Jules」の順になります。そして、角括弧内の「[1]」は、リストの最初の要素である「Verne」を選択します。この値が、xsl:sort関数で使用され、書籍を並び替えるために使用されます。これは完璧な解決策ではありませんが、今回のケースでは機能します。タイトルに関する処理は複雑に見えますが、ロジック自体は単純です。tokenize(title, ' ')[1]という式は、タイトルの最初の単語を抽出します。最初の条件分岐は、「タイトルの最初の単語が「A」であるか?」というものです。もしそうであれば、タイトルの3文字目から始まる部分文字列を返します。これにより、「A」とそれに続く空白が削除されます。もしタイトルの最初の単語が「A」でない場合、次に「タイトルの最初の単語が「The」であるか?」という条件でチェックを行います。もしそうであれば、タイトルの5文字目から始まる部分文字列を使用します。これにより、「The」とそれに続く空白が削除されます。もしどちらの条件も満たされない場合、タイトルをそのままソートキーとして使用します。「An」という単語についても、同様のチェックを追加することも可能ですが、今回のデータセットでは必要ありません。この最後のXSLTを実行すると、以下の出力が得られます。

「マーク・トウェイン」が現在、「ジュール・ヴェルヌ」よりも上位に表示されています。「ハックルベリー・フィンの冒険」は、「カラベラス郡の有名な飛び蛙」や「アーサー王宮廷のコネチカット人」よりも上位に表示されています。著者名の並び順に関する私たちの手法の欠点は、著者名を「ジュール・ヴェルヌ」を「Verne, Jules」として扱うようにしたいという点です。そうすることで、もし「ジミー・ヴェルヌ」という著者の本があった場合、それらは異なる著者として扱われるはずです。しかし、現在のコードではそれが実現されていません。concat(reverse(tokenize(author, ' '))[1], reverse(tokenize(author, ' '))[2])を使用することで、「ジュール・ヴェルヌ」と「ジミー・ヴェルヌ」を正しく並べ替えることができますが、この解決策は2単語の著者名にしか適用できません。もし著者が姓名に付記(「マーティン・ルーサー・キング・ジュニア」など)や複数の単語(「ジョージ・ハーバート・ウォーカー・ブッシュ」など)を持つ場合、このコードは機能しません。著者名のアルファベット順に関する一般的なルールには多くの例外があり、すべてのバリエーションに対応できるコードを作成するには、この記事の範囲をはるかに超える複雑さが必要です。今回示したかったのは、XPath式を使用して、XMLデータを動的に操作する能力です。データソースの形式を常に完全に制御できるわけではありませんが、XPath式の強力さを利用することで、必要な形式にデータを変換することができます。これらの例で使用したファイルのコピーはこちらから入手できます。