开发者

Count the number of elements returned by <call-template>

I have the following xsl stylesheet:

<xsl:stylesheet xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8"/>

  <xsl:template match="/">
    <xsl:variable name="elements">
      <xsl:call-template name="get-some-nodes"/>
    </xsl:variable>

    <root>
      <values>
        <xsl:copy-of select="$elements"/>
      </values>
      <count>
        <xsl:value-of select="count($elements)"/>
      </count>
    </root>
  </xsl:template>

  <xsl:template开发者_Python百科 name="get-some-nodes">
    <node>1</node>
    <node>2</node>
    <node>3</node>
  </xsl:template>

</xsl:stylesheet>

(It shouldn't matter what xml you apply it to, it generates its own data).

The result of this of this (using xsltproc) is:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://www.w3.org/1999/xhtml" xmlns:set="http://exslt.org/sets">
  <values>
    <node>1</node>
    <node>2</node>
    <node>3</node>
  </values>
  <count>1</count>
</root>

Given that the called template returns three nodes, I expected "count($elements)" to be 3, but it is one. I suspected maybe the results were being wrapped up in some sort of root node, but any attempt to do count($elements/*) or similar failed, I believe because $elements is a result tree fragment, and not a node-set.

I don't have access to any of the goodies of exslt or xslt2.0, surely there's a way to get the count of the nodes stored in a variable?

I'd also be happy to count the nodes returned by the call-template without using an intermediate variable, but I can't see how that would be possible.


<xsl:variable name="elements"> 
  <xsl:call-template name="get-some-nodes"/> 
</xsl:variable> 

<root> 
  <values> 
    <xsl:copy-of select="$elements"/> 
  </values> 
  <count> 
    <xsl:value-of select="count($elements)"/> 
  </count> 
</root>

In XSLT 1.0, whenever nodes are copied into the body of an <xsl:variable>, the contents of this variable is an RTF (Result-Tree_fragment) and needs to be converted to a regular tree before further processing with XPath.

An RTF can be converted to a regular tree only using an extension function, ususally named xxx:node-set(), where the xxx prefix is bound to a vendor-specific namespace.

To get the number of elements that are at the top level of this tree, you need:

count(xxx:node-set($elements)/*)

Here are some namespaces, to which xxx: is often bound:

"http://exslt.org/common/"

"urn:schemas-microsoft-com:xslt"

In XSLT 2.0 the RTF "type" no longer exists and you can just have:

count($elements/*)

if the type of $elements isn't specified (the default is document-node())

or

count($elements)

if the type of $elements is specified as element()*

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜