2011-01-07 28 views
3

考虑下面的XML片段:在XSL中可以匹配“none”吗?

<foo> 
    <bar>1</bar> 
    <bar>2</bar> 
    <bar>3</bar> 
</foo> 

下面的XSL应该工作:

<xsl:template match="/"> 
    <xsl:apply-templates 
    mode="items" 
    select="bar" /> 
</xsl:template> 

<xsl:template mode="items" match="bar"> 
    <xsl:value-of select="." /> 
</xsl:template> 

有没有一种方法,我可以使用类似的格式,以这个应用模板,当有没有<bar/>实体?例如:

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

问得好,+1。查看我对exlanation的回答以及仅使用模板并且没有显式条件XSLT指令的完整简短解决方案。 :) –

回答

2

人们还可以使用这个模式,以避免额外的选:

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

工作完美!谢谢!! –

1

没有,当你有apply-templates select="bar"和上下文节点没有任何bar子元素则没有节点进行处理,因此不应用模板。但是,您可以将使用应用模板的模板中的代码更改为

<xsl:choose> 
    <xsl:when test="bar"> 
     <xsl:apply-templates select="bar"/> 
    </xsl:when> 
    <xsl:otherwise>There are not items.</xsl:otherwise> 
    </xsl:choose> 
5

是的。

但逻辑应该是:

<xsl:template match="foo"> 
    <xsl:apply-templates select="bar"/> 
</xsl:template> 

<xsl:template match="foo[not(bar)]"> 
    There are no items. 
</xsl:template> 

注:这是其具有或不具有bar孩子foo元素。

+0

+1。更好的答案。 – Flack

+0

Upvoted,但我已经与@ Flack的答案一样,有时不能使用父上下文。 –

+0

@digitala:没问题。但**总是可以使用这种模式匹配**。 @ Flack的答案使用**推式**('xsl:apply-tempates/@ select')和模式('xsl:apply-tempates/@ mode')代替这种**拉式**。 – 2011-01-07 15:59:10

0

考虑下面的XML片段:

<foo> 
    <bar>1</bar> 
    <bar>2</bar> 
    <bar>3</bar> 
</foo> 

下面的XSL应该工作:

<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:apply-templates>根本不选择任何节点

有没有一种方法,我可以使用类似的 格式这个时候有没有实体应用模板 ?

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

当施加到所提供的XML文档

<foo> 
    <bar>1</bar> 
    <bar>2</bar> 
    <bar>3</bar> 
</foo> 

结果是

3<bar/> s. 

当应用到这个XML文档

<foo> 
    <baz>1</baz> 
    <baz>2</baz> 
    <baz>3</baz> 
</foo> 

结果是

No <bar/> s. 
相关问题