element-available() 関数  
指定された要素が XSLT プロセッサに対して利用できるかどうかを調べます。この関数を使用すると、XML ドキュメントを処理するために特定の要素が利用できない場合でも、正しく応答するスタイルシートを設計できます。
 
入力

要素の名前。この名前は名前空間を使用して設定します。名前空間 URI が XSLT の名前空間 URI と同じである場合、要素名は XSLT によって定義される要素を参照します。それ以外の場合、この名前は拡張要素を参照します。要素名に null 名前空間 URI がある場合、element-available 関数は false を返します。

 
出力

要素が利用できる場合はブール値 true、それ以外の場合は false

 
定義先

XSLT 15 節「Fallback」

 

次の例を使用して element-available() 関数をテストします。

<?xml version="1.0"?>
<book>
  <title>XSLT</title>
  <chapter>
    <title>Getting Started</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>The Hello World Example</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>XPath</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Stylesheet Basics</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Branching and Control Elements</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Functions</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Creating Links and Cross-References</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Sorting and Grouping Elements</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
  <chapter>
    <title>Combining XML Documents</title>
    <para>If this chapter had any text, it would appear here.</para>
  </chapter>
</book>

スタイルシートは次のとおりです。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect"

  xmlns:saxon="http://icl.com/saxon"
  extension-element-prefixes="redirect saxon">

  <xsl:output method="html"/>

  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="element-available('redirect:write')">
        <xsl:for-each select="/book/chapter">
          <redirect:write select="concat('chapter', position(), '.html')">
            <html>
              <head>
                <title><xsl:value-of select="title"/></title>
              </head>
              <body>
                <h1><xsl:value-of select="title"/></h1>
                <xsl:apply-templates select="para"/>
                <xsl:if test="not(position()=1)">
                  <p>
                    <a href="chapter{position()-1}.html">Previous</a>
                  </p>
                </xsl:if>
                <xsl:if test="not(position()=last())">
                  <p>
                    <a href="chapter{position()+1}.html">Next</a>
                  </p>
                </xsl:if>
              </body>
            </html>
          </redirect:write>
        </xsl:for-each>
      </xsl:when>
      <xsl:when test="element-available('saxon:output')">
        <xsl:for-each select="/book/chapter">
          <saxon:output file="chapter{position()}.html">
            <html>
              <head>
                <title><xsl:value-of select="title"/></title>
              </head>
              <body>
                <h1><xsl:value-of select="title"/></h1>
                <xsl:apply-templates select="para"/>
                <xsl:if test="not(position()=1)">
                  <p>
                    <a href="chapter{position()-1}.html">Previous</a>
                  </p>
                </xsl:if>
                <xsl:if test="not(position()=last())">

                  <p>
                    <a href="chapter{position()+1}.html">Next</a>
                  </p>
                </xsl:if>
              </body>
            </html>
          </saxon:output>
        </xsl:for-each>
      </xsl:when>
      <xsl:otherwise>
        <html>
          <head>
            <title><xsl:value-of select="/book/title"/></title>
          </head>
          <xsl:for-each select="/book/chapter">
            <h1><xsl:value-of select="title"/></h1>
            <xsl:apply-templates select="para"/>
          </xsl:for-each>
        </html>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="not(element-available('write'))">
      <xsl:message terminate="no">
        The <write> element is not available!
      </xsl:message>
    </xsl:if>
  </xsl:template>

  <xsl:template match="para">
    <p><xsl:apply-templates select="*|text()"/></p>
  </xsl:template>

</xsl:stylesheet>

このスタイルシートは、XML ファイルのコンテンツを受け取り、その一部を別の HTML ファイルに書き込もうとします。最初の <chapter> 要素はファイル chapter1.html、2 番目の <chapter> 要素はファイル chapter2.html、のように書き込まれます。このスタイルシートは、最初に Xalan の <redirect:write> 要素を使用しようとします。この要素が利用できない場合は、Saxon の <saxon:output> 要素をチェックします。これらのいずれの要素も利用できない場合、すべての <chapter> 要素のコンテンツを同じ出力ストリームに書き込みます。このスタイルシートは、設定されていない要素名 write を使用して element-available() 関数を呼び出します。この呼び出しは常に false を返しますが、これは要素名が名前空間で設定されていないためです。

Xalan を使用し、例のスタイルシートで XML ファイルを処理できる場合、コンソール上の結果は次のようになります。

file:///D:/O'Reilly/XSLT/bookSamples/AppendixC/elementavailable.xsl; Line 66; 
Column 35; The <write> element is not available!

スタイルシートはファイル chapter1.htmlchapter9.html を生成します。各ファイルには、元のファイルの <chapter> 要素の 1 つからのデータが含まれます。このスタイルシートは章のファイル間のハイパーリンクも生成します。chapter3.html を次に示します。

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
      <title>XPath</title>
   </head>
   <body>
      <h1>XPath</h1>
      <p>If this chapter had any text, it would appear here.</p>
      <p><a href="chapter2.html">Previous</a></p>
      <p><a href="chapter4.html">Next</a></p>
   </body>
</html>

このファイルは、ブラウザで表示されると、図 C-1 のようになります。

HTML のサンプル出力ファイル

[Previous] リンクをクリックするとファイル chapter2.html に移動し、[Next] リンクをクリックすると chapter4.html に移動します。

Saxon でスタイルシートを使用すると (コマンド java com.icl.saxon.StyleSheet chapterlist.xml elementavailable.xsl を使用)、コンソール上では、次のように同様の結果が得られます。

The <write> element is not available!

メッセージのフォーマットは少し異なりますが、複数の HTML ファイルの出力は同じになります。

最後に、Oracle XML パーサーを使用すると、クエリーする要素はどれも利用できなくなるので、すべての出力は 1 つのファイルに書き込まれます。次のコマンドでプロセッサを呼び出します。このコマンドは 1 行である必要があります。

java oracle.xml.parser.v2.oraxsl chapterlist.xml 
  elementavailable.xsl chapters.html

コンソール出力を次に示します。

Message: The <write> element is not available!

出力ファイル chapters.html は次のとおりです。

<html xmlns:redirect="org.apache.xalan.xslt.extensions.Redirect" 
  xmlns:saxon="http://icl.com/saxon">
   <head>
      <META http-equiv="Content-Type" content="text/html">
      <title>XSLT</title>
   </head>
   <h1>Getting Started</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>The Hello World Example</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>XPath</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Stylesheet Basics</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Branching and Control Elements</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Functions</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Creating Links and Cross-References</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Sorting and Grouping Elements</h1>
   <p>If this chapter had any text, it would appear here.</p>
   <h1>Combining XML Documents</h1>
   <p>If this chapter had any text, it would appear here.</p>
</html>

この出力の表示を図 C-2 に示します。

すべての章の一覧が含まれた HTML ドキュメント

この例で element-available() 関数を使用すると、どのような処理機能が利用できるかを調べ、どのような要素に対しても正しく応答するようにできます。