[英]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>
徹底閱讀你的問題,我意識到我的最后解決方案無處可去。 我的新答案如下:
由於您需要知道Events
是否有任何元素,您需要更改/
匹配模板:
<xsl:template match="/">
<!-- Stuff -->
<xsl:apply-templates select="/Root/Events" />
<!-- Stuff -->
</xsl:template>
現在,該模板僅匹配填充Events
以及所需的Event
模板:
<xsl:template="Events[count(child::Event) > 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.