Is it possible to match "none" in XSL?
Given the following XML fragment:
<foo>
<bar>1</bar>
<bar>2</bar>
<bar>3</bar>
</foo>
The following XSL should work:
<xsl:template match="/">
<xsl:apply-templates
mode="items"
select="bar" />
</xsl:template>
<xsl:开发者_运维问答template mode="items" match="bar">
<xsl:value-of select="." />
</xsl:template>
Is there a way I can use a similar format to this to apply a template when there are no <bar/>
entities? For example:
<xsl:template match="/">
<xsl:apply-templates
mode="items"
select="bar" />
</xsl:template>
<xsl:template mode="items" match="bar">
<xsl:value-of select="." />
</xsl:template>
<xsl:template mode="items" match="none()">
There are no items.
</xsl:template>
Yes.
But the logic should be:
<xsl:template match="foo">
<xsl:apply-templates select="bar"/>
</xsl:template>
<xsl:template match="foo[not(bar)]">
There are no items.
</xsl:template>
Note: It's foo
element which is having or not having bar
children.
One could also use this pattern to avoid extra chooses:
<xsl:template match="/*">
<xsl:apply-templates select="bar" mode="items"/>
<xsl:apply-templates select="(.)[not(bar)]" mode="show-absence-message"/>
</xsl:template>
<xsl:template match="bar" mode="items">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="/*" mode="show-absence-message">
There are no items.
</xsl:template>
No, when you have apply-templates select="bar"
and the context node does not have any bar
child elements then no nodes are processed and therefore no templates are applied. You could however change your code in the template doing the apply-templates to e.g.
<xsl:choose>
<xsl:when test="bar">
<xsl:apply-templates select="bar"/>
</xsl:when>
<xsl:otherwise>There are not items.</xsl:otherwise>
</xsl:choose>
Given the following XML fragment:
<foo>
<bar>1</bar>
<bar>2</bar>
<bar>3</bar>
</foo>
The following XSL should work:
<xsl:template match="/">
<xsl:apply-templates mode="items" select="bar" />
</xsl:template>
<xsl:template mode="items" match="bar">
<xsl:value-of select="." />
</xsl:template>
No, the <xsl:apply-templates>
above doesn't select any node at all.
Is there a way I can use a similar format to this to apply a template when there are no entities?
Yes:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*[not(bar)]">
No <bar/> s.
</xsl:template>
<xsl:template match="/*[bar]">
<xsl:value-of select="count(bar)"/> <bar/> s.
</xsl:template>
</xsl:stylesheet>
when applied to the provided XML document:
<foo>
<bar>1</bar>
<bar>2</bar>
<bar>3</bar>
</foo>
the result is:
3<bar/> s.
When applied to this XML document:
<foo>
<baz>1</baz>
<baz>2</baz>
<baz>3</baz>
</foo>
the result is:
No <bar/> s.
精彩评论