4

次のような XML 構造があります。

<Root>
  <!-- ...other stuff -->
  <Events>
    <Event date="0000-00-00">Event Description etc...</Event>
    <Event date="0000-00-00">Event Description etc...</Event>
    <Event date="0000-00-00">Event Description etc...</Event>
  </Events>
  <!-- ...other stuff -->
</Root>

次に、スタイルシートに XSLT を次のように配置します。

<xsl:variable name="Events" select="/Root/Events/Event" />

<xsl:template match="/">
  <!-- Stuff -->    
  <xsl:apply-templates select="$Events" />
  <!-- Stuff -->    
</xsl:template>

<xsl:template match="Event">
  <!-- Regular Event Template Transformation here -->
</xsl:template>    

<!-- ERROR HAPPENS HERE -->
<xsl:template match="not(node())">
  <p class="message">There are currently no upcoming events</p>
</xsl:template>

私がやりたいことは、イベントがないときにのみ表示される 2 つのテンプレートを用意することです。XSLT<xsl:choose><xsl:when>テストを使用して要素のカウントを行い、手続き型言語で行うように適切なテンプレートを呼び出すことができることはわかっていますが、テンプレート処理でこれを行う方法を学ぼうとしています。

私が得ているエラーは次 のとおりです。

4

4 に答える 4

8

not(node()) is not a valid XSLT pattern, try this:

<xsl:template match="Event">
  <!-- Regular Event Template Transformation here -->
</xsl:template>    

<xsl:template match="Events[not(Event)]">
  <p class="message">There are currently no upcoming events</p>
</xsl:template>
于 2011-09-06T20:37:22.217 に答える
3

これはうまくいくかもしれません

<xsl:template match="*[not(node())]">
  <!-- ... -->

こちらの回答も参照してください: XSLT To remove empty nodes and nodes with -1

于 2011-09-06T19:30:09.660 に答える
2

新しい答え

あなたの質問をよく読んで、私の最後の解決策があなたをどこにも導いていないことに気付きました。私の新しい答えは次のとおりです。

内部に要素があるかどうかを知る必要があるため、一致するテンプレートEventsを変更する必要があります。/

<xsl:template match="/">
   <!-- Stuff -->    
   <xsl:apply-templates select="/Root/Events" />
   <!-- Stuff -->    
</xsl:template>

Events必要なテンプレートとともにpopulate のみに一致するEventテンプレート:

<xsl:template="Events[count(child::Event) &gt; 0]">
   <xsl:apply-template select='./Event'/>
</xsl:template>

<xsl:template="Event">
    <!-- some stuff -->
</xsl:template>

空の に一致するテンプレートEvents:

<xsl:template="Events[count(child::Event) = 0]">
   <p class="message">There are currently no upcoming events</p>
</xsl:template>

古い答え

試してみてください:

<!-- This matches every node with an empty string repr. Maybe you want
     to replace "self::*" to avoid attributes, etc." -->
<xsl:template match="*[string-length(self::*) = 0]">
</xsl:template>

詳細:

私の記憶が正しければ、XPath/XSL では '*' は任意のタイプのノード (テキスト ノード、要素ノード、コメント ノード、属性ノードなど) に*[string-length(self::*) = 0]一致します。たとえば、他の場所にある場合がありselect='@*'ます。したがって、このテンプレートは要素だけでなく属性にも適用できます。

どの属性とも一致しないことが確実な場合は、そのままにしておくことができます。ただし、コードが正しいアイデアを表現していることは気に入っています。したがって、このテンプレートを Event 要素のみに適用する場合は、次のように一致を変更します。

<xsl:template match="Event[string-length(self::*) = 0]">
</xsl:template>

http://www.w3.org/TR/xsltでXSLT 仕様をのぞいてみると、 * は要素のみに一致するようです。しかし、私はそれをテストします。

于 2011-09-06T19:31:43.283 に答える
1

一致するパターンがノードではなくブール値になるため、プロセッサはエラーをスローします。


この変換を試してください (必要な変数を保持します):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="Events" select="/Root/Events/Event"/>

    <xsl:template match="Root">
        <xsl:apply-templates select="$Events
            | Events[not(Event)]"/>  
    </xsl:template>

    <xsl:template match="Event">
        <p class="message">There is an event</p>
    </xsl:template>    

    <xsl:template match="Events">
        <p class="message">There are currently no upcoming events</p>
    </xsl:template>

</xsl:stylesheet>

入力に適用すると、以下が生成されます。

<p class="message">There is an event</p>
<p class="message">There is an event</p>
<p class="message">There is an event</p>

次のようなイベントのない入力に適用された場合:

<Root>
  <Events/>
</Root>

生成:

<p class="message">There are currently no upcoming events</p>
于 2011-09-06T19:50:26.903 に答える