2010-11-15 52 views
4

我有以下XSL样式表:计数由<调用模板>返回元素的数量

<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 name="get-some-nodes"> 
    <node>1</node> 
    <node>2</node> 
    <node>3</node> 
    </xsl:template> 

</xsl:stylesheet> 

(它不应该不管你申请什么XML它,它会生成自己的数据)。

的这本(使用xsltproc的)的结果是:

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

鉴于所谓的模板返回三个节点,我希望“计数($元素)”为3,但它是一个。我怀疑也许结果被包装在某种根节点,但任何尝试计数($ elements/*)或类似失败,我相信因为$元素是一个结果树片段,而不是一个节点集。

我无法获得exslt或xslt2.0的任何好东西,当然有一种方法可以获得存储在变量中的节点的数量吗?

我也很乐意计算调用模板返回的节点而不使用中间变量,但我不明白这怎么可能。

+0

好问题,1。请参阅我的答案以获取详细的解释和解决方案 – 2010-11-15 23:29:23

回答

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

在XSLT 1.0,每当节点被复制到一个<xsl:variable>的主体中,此变量的内容是一个RTF(结果-Tree_fragment)并且需要被转换为正则树在用XPath进一步处理之前。

只能使用扩展函数(通常命名为xxx:node-set())将RTF转换为常规树,其中xxx前缀绑定到供应商特定的命名空间。

若要取得这棵树的顶层元素的数量,您需要:

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

这里有一些命名空间,到xxx:经常势必

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

"urn:schemas-microsoft-com:xslt" 

在XSLT 2.0中,RTF“类型”不再存在,您可以只有

count($elements/*) 

如果未指定的$elements类型(默认为document-node()

count($elements) 

如果$elements类型被指定为element()*

+0

很好的答案,但我不认为我有可用的节点集功能。我最终计划将此作为合并(atlassian的wiki产品)页面进行部署,并且在实验之后,它似乎不支持这些扩展。不幸的是,我正在寻找一种香草的XSLT 1解决方案。 – gfxmonk 2010-11-16 00:17:24

+0

@gfxmonk:您的XSLT处理器很可能具有* xxx:node-set()函数 - 大多数XSLT处理器都有。什么是您使用的XSLT处理器?如果你不知道,从这个函数得到结果:'system-property(xsl:vendor)'或'system-property(xsl:vendor-url)'。 – 2010-11-16 02:06:13

+0

啊,这是一个很好的把戏知道。我正在使用Apache xalan-j。但是,我打算使用多个xslt处理器(xalan和libxslt)来运行此操作,因此我仍然非常喜欢不使用此类扩展的解决方案。 – gfxmonk 2010-11-16 03:03:00

相关问题