簡體   English   中英

XSLT匹配空節點

[英]XSLT matching empty nodes

我有一個像以下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>

我想要做的是有兩個模板,一個僅在沒有事件時顯示。 我知道我可以使用XSLT與<xsl:choose><xsl:when>測試進行元素計數,只需調用正確的模板,就像我在過程語言中所做的那樣,但我正在努力學習如何做到這一點與模板處理。

我得到的錯誤是: 表達式的預期結束,找到'('。not - >(< - node())

not(node())不是有效的XSLT模式,試試這個:

<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>

這可能會更好

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

另請參見此答案: XSLT使用-1刪除空節點和節點

新答案

徹底閱讀你的問題,我意識到我的最后解決方案無處可去。 我的新答案如下:

由於您需要知道Events是否有任何元素,您需要更改/匹配模板:

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

現在,該模板僅匹配填充Events以及所需的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規范,似乎*只匹配元素。 但是,我會測試它。

您的處理器會拋出錯誤,因為匹配的模式會導致布爾值而不是節點。


嘗試這個轉換(保留所需的變量):

<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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM