-----
<?xml version="1.0"?>
<people>
<person>
<name>安倍 晋三</naem>
<kana>あべ しんぞう</kana>
</person>
<person>
<name>菅 義偉</naem>
<kana>すが よしひで</kana>
</person>
<person>
<name>麻生 太郎</naem>
<kana>あそう たろう</kana>
</person>
<person>
<name>柳澤 伯夫</naem>
<kana>やなぎさわ はくお</kana>
</person>
</people>
-----
このXMLから下記のようなアイウエオ順の一覧表のHTMLを生成するXSLを作りたいと思います。
-----
<html>
ア行<br>
安倍 晋三<br>
麻生 太郎<br>
<br>
サ行<br>
菅 義偉<br>
<br>
ヤ行<br>
柳澤 伯夫<br>
</html>
-----
条件、
・parsonの総数は未知で、アイウエオ順にはなっていません。
・「ア行」のように該当の行が複数ある場合も「ア行」という行名は1度だけ表示します。
・「カ行」のように該当の行に属する要素がない場合は「カ行」という行名自体を表示しません。
皆さんのお知恵を貸していただけないでしょうか。
よろしくお願いします。
XSLTスタイルシート書き方講座(4):XSLTのソートとパラメータ
XSLTスタイルシート書き方講座 応用編(2):XMLデータの埋め込みと相互参照
外部にカナのインデックスを持たせて、メインのデータからインデックスに一致する要素をだけを出力する。。。。なんて方法で作ってみました。
メインデータを何度も走査するのであまりスマートな方法とはいえないかもしれません。
----
下記xmlをインデックスに使います。『kana.xml』として保存してください。
<?xml version="1.0" encoding="Shift_JIS"?> <root> <kanas> <kana> <kana_h>ア行</kana_h> <kana_k>あいうえおアイウエオ</kana_k> </kana> <kana> <kana_h>カ行</kana_h> <kana_k>かきくけこカキクケコがぎぐげごガギグゲゴ</kana_k> </kana> <kana> <kana_h>サ行</kana_h> <kana_k>さしすせそサシスセソざじずぜぞザジズゼゾ</kana_k> </kana> <kana> <kana_h>タ行</kana_h> <kana_k>たちつてとタチツテトだぢづでどダヂヅデド</kana_k> </kana> <kana> <kana_h>ナ行</kana_h> <kana_k>なにぬねのナニヌネノ</kana_k> </kana> <kana> <kana_h>ハ行</kana_h> <kana_k>はひふへほハヒフヘホばびぶべぼぱぴぷぺぽバビブベボパピプペポ</kana_k> </kana> <kana> <kana_h>マ行</kana_h> <kana_k>まみむめもマミムメモ</kana_k> </kana> <kana> <kana_h>ヤ行</kana_h> <kana_k>やゆよヤユヨ</kana_k> </kana> <kana> <kana_h>ラ行</kana_h> <kana_k>らりるれろラリルレロ</kana_k> </kana> <kana> <kana_h>ワ行</kana_h> <kana_k>わゐゑをワヰヱヲ</kana_k> </kana> <kana> <kana_h>その他</kana_h> <kana_k>ぁぃぅぇぉっゃゅょゎァィゥェォッャュョヮ</kana_k> </kana> </kanas> </root>
下記xmlをスタイルシートにします。
<?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html" encoding="Shift_JIS"/> <xsl:template match="/"> <html> <head> <title>何かの一覧表</title> </head> <body> <h1>何かの一覧表</h1> <xsl:variable name="datas" select="//people"/><!-- メインデータを丸ごと変数に入れておく --> <xsl:variable name="kanas" select="document('kana.xml')"/><!-- インデックスファイルを読み込む --> <xsl:for-each select="$kanas//kana"><!-- インデックスファイルを全件ループ --> <xsl:call-template name="people"> <xsl:with-param name="datas" select="$datas" /> <xsl:with-param name="kana_h" select="kana_h" /> <xsl:with-param name="kana_k" select="kana_k" /> </xsl:call-template> </xsl:for-each> </body> </html> </xsl:template> <xsl:template name="people"> <xsl:param name="datas"/><!-- メインデータ全部 --> <xsl:param name="kana_k"/><!-- 今回調査する文字(ex.あいうえお....) --> <xsl:param name="kana_h"/><!-- 今回調査する行の見出し --> <xsl:if test="not(count($datas/person/kana[contains($kana_k, substring(.,1,1))])=0)"> <table frame="border"> <caption><xsl:value-of select="$kana_h"/></caption> <tr> <th>氏名</th> <th>カナ</th> </tr> <xsl:for-each select="$datas/person"> <xsl:sort select="kana" data-type="text" /> <xsl:if test="contains($kana_k, substring(kana,1,1))"> <tr> <td><xsl:value-of select="name"/></td> <td><xsl:value-of select="kana"/></td> </tr> </xsl:if> </xsl:for-each> </table> </xsl:if> </xsl:template> </xsl:stylesheet>
あとは、適当なツールでpersonのxmlを上記スタイルシートで変換してください。
----
コメント(2件)
出力のHTMLで、
「安倍 晋三」と「麻生 太郎」の順序がアイウエオ順になっていませんでした。
正しくはこちらもアイウエオ順で、
「麻生 太郎」→「安倍 晋三」と並びます。
よろしくお願いします。
お礼が遅れました。
ご回答ありがとうございました。
ただちに検証のうえ、活用を図ります。