Java入門 / Web入門

【Java Web入門 #12】標準タグライブラリ(JSTL)の利用(4)|XMLタグライブラリ

2025.02.28

JSTLのXMLタグライブラリは、XMLドキュメントの読み込みや変換のためのライブラリです。当記事では、XMLタグライブラリの概要と各タグの仕様について説明します。

◆Java Web入門の過去記事はこちら
◆Java入門 記事一覧はこちら

XMLタグライブラリの概要

JSTLのXMLタグライブラリは、JSP上でXMLドキュメントを効率的に利用することを目的としたタグライブラリです。

XMLタグライブラリでは、XMLドキュメントの一部を指定および選択するための簡潔な表記法である式言語「XPath」を利用して、XMLの要素や属性にアクセスしたり、条件を指定して要素を取り出したりすることができます。

XML文書の扱いについても、近年のアプリケーションでは、軽量かつJavaScriptと親和性の高い JSON形式データの利用が多く、以前ほど利用頻度は高くありませんが、XMLタグライブラリは簡単なXMLデータの処理の学習や、既存のJSPアプリケーションの保守・改修などの場面で活用できます。

taglibディレクティブ

XMLタグライブラリのプレフィックスには、通例として「x」が利用されます。(当記事でもプレフィックスを「x」として説明します)

(JSTL3.0の場合)

Java
<%@ taglib uri="jakarta.tags.XML" prefix="x" %>


(JSTL2.0以前の場合)

Java
<%@ taglib uri="http://java.sun.com/jsp/jstl/XML" prefix="x" %>

各タグの仕様

利用の前に(説明の前提条件)

XMLタグライブラリの利用の前に、Webアプリケーション上に読み込むXMLファイルを作成して、URLでアクセス可能なようにしておきます。

今回は、以下の内容でXMLファイル「datatype.xml」を作成し、src/main/webapp/xml フォルダに格納しました。

XML
<?xml version="1.1" encoding="UTF-8" ?>
<root>
  <data out="true">
    <id>1</id>
    <name>文字列</name>
    <type>String</type>
  </data>
  <data out="true">
    <id>2</id>
    <name>数値</name>
    <type>Number</type>
  </data>
  <data out="false">
    <id>3</id>
    <name>真偽値</name>
    <type>Boolean</type>
  </data>
  <data out="true">
    <id>4</id>
    <name>日付</name>
    <type>Date</type>
  </data>
  <link>
    <html>
     ※下記参照
    </html>
  </link>
</root>
<link><html>内の「※下記参照」の部分は、以下の内容に置き換えてください。  

  &lt;a href="https://knovus.site/primer_java/gsi/1012/"&gt;
  【Java Web入門 #9】標準タグライブラリ(JSTL)の利用(1)
  &lt;/a&gt;


ファイルを保存したらtomcatを起動し、ブラウザからアクセスできることを確認しておきます。


以降、各タグの説明やサンプルコードについては、このファイルが準備されているものとして作成していますのでご注意ください。

XMLの基本処理

<x:parse>

<x:parse>タグは、XMLドキュメントを解析し、JavaコードやJSP上で扱うためにオブジェクト化します。

属性名必須説明
doc解析対象のXMLドキュメントを指定する。
(XML文字列またはjava.io.Reader オブジェクト)
systemIdXMLドキュメントを解析するためのシステム識別子 (URI)を指定する。
filterXMLドキュメントをオブジェクト化する際に適用するフィルタリングを指定する。(org.xml.sax.XMLFilterオブジェクト)
varパースされたオブジェクトを保持するための変数名を指定する。
scopevar で指定した変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
varDomパースされたオブジェクトを保持するための変数名を指定する。
scopeDomvarDom で指定した変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
xml[非推奨]
※XMLドキュメントの指定には doc 属性を利用してください。
(可)


<x:parse>タグは通常<c:import>タグと組み合わせて利用し、XMLファイルをインポートしてリソースとなる文字列を読み込み、内容を解析のしてXMLを操作するためのDOMオブジェクトを作成します。このとき、filter によってフィルタリングすることで、生成されるオブジェクトを最小限のサイズとすることも可能です。

また、<c:import>タグで外部のURLを指定して、XMLファイルをリソースとしてインポートすることで、外部サイトのRSSフィードの解析を行ったりすることも可能です。例えば、Yahoo! ニュース のサイトでは、カテゴリごとに多くのRSSが準備されています。
※参考: Yahoo! ニュース RSS一覧 (外部サイト)

HTML
<%-- 準備したXMLファイルを解析 --%>
<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<x:parse var="dom" doc="${xmlData}" />

<%-- 外部サイト(Yahoo! ニュース)のRSSを解析 --%>
<c:import url="https://news.yahoo.co.jp/rss/categories/it.xml" var="rssData" charEncoding="UTF-8"/>
<x:parse var="rssDom" doc="${rssData}" />


var 属性または varDom 属性は、いずれか片方のみしか指定できません。これらは同一の解析結果が格納されますが、var 属性を指定した場合はObject 型として、varDom 属性を指定した場合は org.w3c.dom.Document 型として渡される点が異なります。これは カスタムタグとの連携のために準備されていますので、カスタムタグへ引き渡す必要がなければ通常は var を指定して問題ありません。

<x:out>

<x:out>タグは、XMLの要素を出力します。select属性にXPath式を記述することで、対象のXML(DOMオブジェクト)の中から、出力対象の要素を指定することが可能です。

属性名必須説明
select出力対象を取得する条件をXPath式で記述する。
escapeXmlXMLやHTMLに利用される所定の文字を出力する際に、エスケープするかどうかを true(デフォルト)/false のいずれかで指定する。
「< (→ &gt; )」「> (→ &lt; )」「 " (→ &quot; )」「 ' (→ &apos; )」「& (→ &amp; )」の5文字が対象。


<c:out>タグと同様に、escapeXml属性をfalseを指定した場合、XMLの要素の値がHTML文字列であったときに、そのままHTMLとして出力されます。

HTML
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
<%@ taglib uri="jakarta.tags.xml" prefix="x" %>

<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<x:parse var="dom" doc="${xmlData}" />

<html>
  <head>
    <title>XMLタグライブラリの動作</title>
  </head>
  <body>
    <p>【escapeXml=true(デフォルト)}</p>
    <x:out select="$dom/root/link/html"/>
    <hr/>

    <p>【escapeXml=false】</p>
    <x:out select="$dom/root/link/html" escapeXml="false"/>
  </body>
</html>


実行結果:

<x:set>

<x:set>タグは、既存のオブジェクトに対して全部または一部を取り出したオブジェクトを作成します。<x:out>タグ同様に、XPath式を利用することで条件に合致する部分だけを抜き出すことも可能です。

属性名必須説明
selectXMLオブジェクトとして取得する条件をXPath式で記述する。
var取得した要素または属性の値を保持する変数名を指定する。
scope変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)


大きなXMLドキュメントの一部だけに対して繰り返し処理などを行う場合、<x:set>タグで対象の箇所を切り出しておくことで、可読性やパフォーマンスの改善につながる場合があります。

下記のサンプルでは、元のXMLの<data>要素の中から、属性 out の値が true のデータだけを選択してvalidItems に保存しています。

HTML
<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<x:parse var="dom" doc="${xmlData}" />

<%-- 条件を指定して絞り込んだDOMオブジェクト --%>
<x:set var="validItems" select="$dom/root/data[@out='true']" /> 

フロー制御(繰り返し・条件判定)

<x:forEach>

<x:forEach>タグは、XMLの複数要素に対して繰り返し処理を行います。

属性名必須説明
selectループ処理を行う対象の要素へのXPathを指定する。
beginループを開始するインデックスを0以上の数値で指定する。
デフォルト値は 0 (先頭から処理)。
endループを終了するインデックスを0以上の数値で指定する。
デフォルトは最後まで。
stepループごとにインデックスをいくつ進めるかを1以上の数値で指定する。
デフォルトは 1 。
varループごとに、ループ対象から取得した要素を保持する変数名を指定する。
varStatusループの状態や情報にアクセスするためのオブジェクトを格納する変数名を指定する。
※取得できるループに関する情報は<c:forEach>タグを参照


<c:forEach>タグでは配列やコレクションに対して繰り返し処理を行いましたが、<x:forEach>タグは select 属性で指定した条件に合致する要素の集合に対して繰り返し処理を行います。

varStatusで取得できるループに関する情報は<c:forEach>タグと同一です。

HTML
<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<x:parse var="dom" doc="${xmlData}" />

<%-- $dom/root/data の全要素に対して繰り返し処理を行う --%>
<x:forEach select="$dom/root/data" var="dataItem">
  
  <%-- ループ中はvarで指定した名前(dataItem)を利用し、XPathでループ各要素にアクセス可能 --%>
  <x:out select="$dataItem/id" />
</x:forEach>

<x:if>

<x:if>タグは、対象のXML要素が条件に合致するかどうかを判定します。

属性名必須説明
selectXMLオブジェクトの判定条件をXPath式で記述する。
var判定した結果(boolean値)を格納する変数名を指定する。
scopevar で指定した変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)


<c:if>タグが test 属性に記述した式で判定を行ったのに対し、<x:if>タグは select 要素に記述したXPath式で判定します。条件に合致した場合のみボディ部の出力を行います。var 属性を指定した場合は判定結果(Boolean値)を保持しておけるため、後続のEL式などでも利用することができます。

HTML
<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<x:parse var="dom" doc="${xmlData}" />

<%-- 1行目のdataだけを抜き出したDOMオブジェクト --%>
<x:set var="firstData" select="$dom/root/data[1]" /> 

<x:if var="result" select="$firstData[id > 0]">
  <x:out select="$firstData/id" />
</x:if>

<%-- 判定結果(Boolean)はEL式などでも利用可能 --%>
<c:if test="${result}">
  1行目のデータは<x:out select="$firstData/name" />
</c:if>

<x:choose> および <x:when><x:otherwise>

<x:choose> および <x:when><x:otherwise>のタグは、複数の条件を設定して、合致した条件の箇所のみ出力することができます。これらのタグは、必ず組み合わせて使用する必要があります。(いずれのタグも単独での使用はできません)

属性名必須説明
selectXMLオブジェクトの判定条件をXPath式で記述する。
※<x:choose>タグ、<x:otherwise>タグは属性を持たない


これらのタグの動作は、<c:choose> および <c:when><c:otherwise>タグの動作とほぼ同じですが、判定を行う対象がXMLオブジェクトであることと、<x:when>タグでは select 属性でXPathを用いた評価を行える点が異なります。

フロー制御の使用例


以下のサンプルでは、作成したXMLファイルを読み込み、XMLタグを利用して条件に合った要素を出力しています。

HTML
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
<%@ taglib uri="jakarta.tags.xml" prefix="x" %>

<%-- ファイル(リソース)のインポート --%>
<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>

<%-- 解析してDOMオブジェクトに --%>
<x:parse var="dom" doc="${xmlData}" />

<html>
  <head>
    <title>XMLタグライブラリの動作</title>
  </head>
  <body>
  
  <p>【全データ】</p>
   
  <%-- dataタグのリストの数だけループ(x:foreach) --%> 
  <x:forEach select="$dom/root/data" var="dataItem">

    <%-- XPath式の判定で処理を振り分け(x:choose/when/otherwise) --%> 
    <x:choose>
      <x:when select="$dataItem[id mod 2 = 0]">
        <div>
          <%-- 要素の出力(x:out) --%>
          [<x:out select="$dataItem/id"/>]
          <x:out select="$dataItem/name"/>
          <x:out select="$dataItem/type"/>
      </x:when>
      <x:otherwise>
        <div style="background-color:#EEE;">
          [<x:out select="$dataItem/id"/>]
          <x:out select="$dataItem/name"/>
          <x:out select="$dataItem/type"/>
      </x:otherwise>
    </x:choose>

    <%-- XPath式の判定で処理を振り分け(x:if) --%> 
    <x:if select="$dataItem[@out='false']" var="result">
    (非表示)
    </x:if>

    </div>
  </x:forEach>

  <hr/>

  <p>【表示データのみ】</p>
  
<%-- 条件に合致する部分のみ抜き出したDOMを作成(x:set) --%>
<x:set var="validList" select="$dom/root/data[@out='true']" />
  
  <x:forEach select="$validList" var="dataItem">
      [<x:out select="$dataItem/id"/>]<x:out select="$dataItem/name"/><x:out select="$dataItem/type"/>
      <br/>
  </x:forEach>

  </body>
</html>


実行結果:

変換処理

<x:transform>

<x:transform>タグは、XMLデータのデータ構造を変換させる「XSLT スタイルシート」を利用して、変換処理を行います。

属性名必須説明
doc変換処理対象のXMLドキュメントを指定する。
(XML文字列、java.io.Reader オブジェクト、javax.xml.transform.Source オブジェクト、org.w3c.dom.Documen オブジェクト(<x:parse><x:set>タグでvarに格納したものを含む)のいずれか)
docSystemIdXMLドキュメントを解析するためのシステム識別子 (URI)を指定する。
xslt変換処理に利用するXSLTスタイルシートを指定する。
(文字列、java.io.Reader オブジェクト、javax.xml.transform.Source オブジェクトのいずれか)
xsltSystemIdXSLT スタイルシートを解析するためのシステム識別子 (URI)を指定する。
result変換結果を保持する javax.xml.transform.Result オブジェクトを指定する。
varパースしたXMLオブジェクトを保持するための変数名を指定する。
scopevar で指定した変数のスコープを指定する。
(page(デフォルト)/request/session/application のいずれか)
xml[非推奨]
※XMLドキュメントの指定には doc 属性を利用してください。
(可)
xmlSystemId[非推奨]
※doc 属性および docSystemId 属性を利用してください。
(可)


var および result のいずれも指定しなかった場合、変換結果はそのままJSPページに出力されます。var を指定した場合は org.w3c.dom.Document オブジェクト、resultを指定した場合はjavax.xml.transform.Result オブジェクトとして変換された結果が格納されます。

この変換は、XMLデータをHTMLのオブジェクト(HTMLタグ)に適用させたり、ブラウザで表示するためのスタイルを付加させたりするために利用できます。

<x:param>

<x:param>タグは<x:transform>タグの要素として利用され、単独では利用されません。

<x:transform>タグでXSLTスタイルシートを用いてXMLオブジェクトに変換する際に、XSLTスタイルシート上のパラメーターに対して値を指定するために利用されます。

属性名必須説明
nameXSLTスタイルシートに定義されているパラメーター名を指定する。
valueXSLTスタイルシートのパラメーターに設定する値を指定する。

変換処理の使用例

変換処理を行うためのXSLTスタイルシートを作成して保存しておきます。ここでは、以下の内容で「trans.xsl」を作成し、src/main/webapp/xsl フォルダに格納しました。

XML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="bgColor"/>
  
  <xsl:template match="/root">
    <xsl:for-each select="data">
      <div style="background-color: {$bgColor};">
        [<xsl:value-of select="id"/>]
        <xsl:value-of select="name"/>
        <xsl:value-of select="type"/>
      </div>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


変換処理を実行するJSPファイルを作成します。<x:transform>タグによって、XMLのデータがXSLTスタイルシートの内容に従って変換されたHTMLが出力されます。

HTML
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="jakarta.tags.core" prefix="c" %>
<%@ taglib uri="jakarta.tags.xml" prefix="x" %>

<c:import url="http://localhost:8080/WebPractice/xml/datatype.xml" var="xmlData" charEncoding="UTF-8"/>
<c:import url="http://localhost:8080/WebPractice/xslt/trans.xsl" var="xlsStyle" charEncoding="UTF-8"/>

<html>
  <head>
    <title>XMLタグライブラリの動作</title>
  </head>
  <body>
    <%-- XMLデータとXSLTスタイルシートを利用してHTMLに変換 --%>
    <x:transform doc="${xmlData}" xslt="${xlsStyle}">
      <%-- XSLTスタイルシートにパラメータ値を指定 --%>
      <x:param name="bgColor" value="#FEC" />
    </x:transform>
  </body>
</html>


実行結果:


参考:Jakarta Standard Tag Library 3.0 Specification Document(公式サイト・英語)
参考:Jakarta Standard Tag Library 3.0 Tagdoc(公式サイト・英語)



いかがでしたでしょうか。JSONでのデータ通信が多くなったとはいえ、XMLはRSSフィードやWebサービス間のデータ交換、エンタープライズシステムの連携など適している場面も依然として存在しており、既存サイトの保守・改修でも必要な技術です。

次回は残りのJSTLタグ、SQLタグライブラリについて解説します。

株式会社GSI 採用サイト

新しいこと、始めよう

あなたとともに歩を進めるWEBメディア

広告

広告