下記のようなXMLがあります。


-----
<?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度だけ表示します。
・「カ行」のように該当の行に属する要素がない場合は「カ行」という行名自体を表示しません。

皆さんのお知恵を貸していただけないでしょうか。

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2007/05/11 18:00:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答1件)

id:mj99 No.1

回答回数138ベストアンサー獲得回数38

ポイント60pt

XSLTスタイルシート書き方講座(4):XSLTのソートとパラメータ

XSLTスタイルシート書き方講座 応用編(2):XMLデータの埋め込みと相互参照

サンプルで覚えるXSLTプログラミング


外部にカナのインデックスを持たせて、メインのデータからインデックスに一致する要素をだけを出力する。。。。なんて方法で作ってみました。

メインデータを何度も走査するのであまりスマートな方法とはいえないかもしれません。

----

下記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を上記スタイルシートで変換してください。

----

  • id:kuroda
    すみません!自己レスです。
    出力のHTMLで、
    「安倍 晋三」と「麻生 太郎」の順序がアイウエオ順になっていませんでした。
    正しくはこちらもアイウエオ順で、
    「麻生 太郎」→「安倍 晋三」と並びます。
    よろしくお願いします。
  • id:kuroda
    mj99 様

    お礼が遅れました。
    ご回答ありがとうございました。

    ただちに検証のうえ、活用を図ります。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません