开发者

Is it possible to match "none" in XSL?

开发者 https://www.devze.com 2023-02-03 13:59 出处:网络
Given the following XML fragment: <foo> <bar>1</bar> <bar>2</bar> <bar>3</bar>

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

精彩评论

暂无评论...
验证码 换一张
取 消