これは、XSL-FO を生成するより複雑な XSLT 1.0 スタイルシートで私が抱えているマッチングの問題の簡単な例です。
<Library>
0 個以上の<Item>
ノードを含む可能性があるこの入力 XML を考えると、
<Library>
<Item type="magazine" title="Rum"/>
<Item type="book" title="Foo" author="Bar"/>
<Item type="book" title="Fib" author="Fub"/>
<Item type="magazine" title="Baz"/>
</Library>
そして、この XSLT:
<xsl:template match="Library">
<xsl:apply-templates select="Item[@type='Magazine']/>
<!-- How to call "NoMagazines" from here? -->
<xsl:apply-templates select="Item[@type='Book']/>
<!-- How to call "NoBooks" from here? -->
</xsl:template>
<xsl:template match="Item[@type='book']">
<!-- do something with books -->
</xsl:template>
<xsl:template match="Item[@type='magazine']">
<!-- do something with magazines -->
</xsl:template>
<!-- how to call this template? -->
<xsl:template name="NoBooks">
Sorry, No Books!
</xsl:template>
<!-- how to call this template? -->
<xsl:template name="NoMagazines">
Sorry, No Magazines!
</xsl:template>
代わりの「ごめんなさい、ダメ!」を作りたいです。タイプ [whatever] のノードLibrary
がない場合のテンプレートからのメッセージ。Item
これまでのところ、私が行った唯一の(醜い)解決策は、子ノードを変数にタイプ別に選択し、変数をテストしてから、変数にノードが含まれている場合はテンプレートを適用するか、適切な「一致しない」名前付きテンプレートを呼び出すことです。変数は空です (ノードが選択されていない場合、test="$foo" は false を返すと想定していますが、まだ試していません):
<xsl:template match="Library">
<xsl:variable name="books" select="Items[@type='book']"/>
<xsl:choose>
<xsl:when test="$books">
<xsl:apply-templates select="$books"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="NoBooks"/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="magazines" select="Items[@type='magazine']"/>
<xsl:choose>
<xsl:when test="$magazines">
<xsl:apply-templates select="$magazines"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="NoMagazines"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
これは (GoF の意味での) XSLT デザイン パターンに違いないと思いましたが、オンラインで例を見つけることができませんでした。どんな提案も大歓迎です!