連載
» 2003年08月20日 10時00分 公開

XMLテクニック集(4):多階層のXML文書にナンバリング処理を行う (1/3)

[山田祥寛,@IT]

多階層のXML文書にナンバリング処理を行う

アイコン

XMLで階層ごとにタイトルが付く文書(論文や書籍原稿)を扱う際に、タイトルの頭に章、節、項の番号を自動的に付加できると便利です。今回は<xsl:number>要素を使って、自動ナンバリングを実現します。

カテゴリ XSLT
関連要素 <xsl:number>
関連記事 フラットな階層のXML文書で階層的なナンバリング処理

 例えば、書籍の目次を想定してみましょう。多くの書籍では、章、節などという単位で階層構造が設定されています。ページ数の多い書籍では、さらに、部、章、節、項、小項などと細分されているかもしれません。

 このような多階層から構成されるXML文書に、階層を意識したナンバリングを行いたい場合、XSLTでは<xsl:number>要素を用いることで実現できます。

(1)<xsl:number>を使ったナンバリング

 まず、以下の例を見てみましょう。contents.xmlは、章(<chapter>要素)と節(<section>要素)を持つ、ある書籍の目次のXMLです。これをXSLTスタイルシートcontents.xslによって、1.1、1.2、2.1、…のように自動ナンバリングしてみることにします。

[contents.xml]
<?xml version="1.0" encoding="Shift_JIS" ?>
<?xml-stylesheet type="text/xsl" href="contents.xsl" ?>
<book title="10日でおぼえるJakarta入門教室">
  <chapter title="オリエンテーション">
    <section title="Jakartaの基礎知識" />
    <section title="Windowsにおける環境設定の方法" />
    <section title="Linuxにおける環境設定の方法" />
  </chapter>
  <chapter title="JSP/サーブレットの基本を学ぶ">
    <section title="JSPの基本を学ぼう" />
    <section title="サーブレットの基本を学ぼう" />
    <section title="JavaBeansの基本を学ぼう" />
  </chapter>
  <chapter title="Strutsの基本構成を学ぶ">
    <section title="Strutsからあなたに「こんにちは」" />
    <section title="「Struts」から「ストラッツ」に" />
  </chapter>
  <chapter title="Strutsで簡単アプリケーションを作成する">
    <section title="ActionFormBeansでフォームを制御する" />
    <section title="ActionFormBeansでデータ検証を行う" />
  </chapter>
</book>
[contents.xsl]
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsl:stylesheet
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 version="1.0">
  <xsl:template match="/">
    <html>
    <head>
    <title><xsl:value-of select="book/@title" /></title>
    </head>
    <body>
    <xsl:for-each select="//chapter|//section">
      <xsl:number level="multiple"
                  format="01 " 
                  count="chapter|section" />
      <xsl:value-of select="@title" /><br />
    </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
章、節が自動的にナンバリングされた 章、節が自動的にナンバリングされた

 ポイントは、以下の部分です。

<xsl:for-each select="//chapter|//section">
  <xsl:number level="multiple"
              format="1 " 
              count="chapter|section" />
  <xsl:value-of select="@title" /><br />
</xsl:for-each>

(2)<xsl:for-each>要素と<xsl:number>要素の役割

 <xsl:for-each>要素の「select="//chapter|//section"」は、すべての<chapter>、<section>要素に合致することを意味します。「/」は直下の要素のみを表しますが、「//」は配下の全要素を表す点に注意してください。

 ナンバリングを処理するのは、<xsl:number>要素の役割です。format属性はナンバリングの出力形式(1、01、A、a、i、Iなど)を、count属性はカウントする対象のノードを、それぞれ表します。つまり、ここでは合致した<chapter>、<section>の両要素についてカウントを行うことを意味します(「|」は「ユニオン」といい、前後の要素の結合を表します)。

 level属性はナンバリングのレベルを表し、設定値“multiple”で指定した場合には、カレントノードのナンバリングのみならず、親要素のナンバリングを頭に付加します。つまり、<chapter>要素は章番号を1、2、3…のように出力しますが、<section>要素は節番号を1、2、3…のように出力するのみならず、1.1、1.2、2.1…のように章番号(親要素のナンバリング)を頭に付加した形で出力するというわけです。

 ちなみに、level属性は設定値として“multiple”のほか、“single”、“any”を取ることができます。それぞれ上のcontents.xslの該当部を“single”、“any”に変更したときの結果を見てみることにしましょう。

level属性が“single”の場合。単純にカレントノードごとのインデックスを表示 level属性が“single”の場合。単純にカレントノードごとのインデックスを表示
level属性が“any”の場合。count属性にマッチした順にナンバリング level属性が“any”の場合。count属性にマッチした順にナンバリング
       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。