如何在XSLT的for-each或xsl:template中统计XML节点出现次数?
解决XSLT中动态统计XML节点出现次数的问题
你当前的XSLT代码里,统计节点数量的逻辑出了核心问题——变量引用方式错误,导致XPath无法识别你提取的动态ID值,所以count结果一直是0。
问题根源
你写的count(//*[contains(element0,'$idNM')])里,'$idNM'会被当成字面字符串处理,XPath不会把它解析成你定义的变量$idNM。而且这里用contains也不合适,因为你需要的是精确匹配element0从第8位开始的14个字符,而不是包含某个字符串。
修正后的XSLT代码
把统计逻辑的XPath改成直接引用变量,并且用精确匹配的方式:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:java="http://xml.apache.org/xslt/java"> <xsl:output method="xml" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <liste> <xsl:apply-templates/> </liste> </xsl:template> <xsl:template match="XMLCreators"> <xsl:apply-templates select="row"/> </xsl:template> <xsl:template match="row"> <xsl:apply-templates select="element0"/> </xsl:template> <xsl:template match="element0"> <xsl:variable name="idNM" select="normalize-space(substring(., 8, 14))" /> <nm id="{$idNM}"> <count> <xsl:value-of select="count(//element0[substring(., 8, 14) = $idNM])" /> </count> </nm> </xsl:template> </xsl:stylesheet>
关键修改点
- 把
<nm>的属性写法简化成<nm id="{$idNM}">,这是XSLT 1.0的属性值模板语法,代码更简洁。 - 统计的XPath改成
count(//element0[substring(., 8, 14) = $idNM]):- 直接引用变量
$idNM,不需要加引号 - 用
substring(., 8, 14) = $idNM做精确匹配,确保统计的是和当前节点子串完全一致的所有element0节点数量
- 直接引用变量
验证输出
用修正后的代码处理你的XML输入,就能得到你期望的输出:
<liste xmlns:java="http://xml.apache.org/xslt/java"> <nm id="760492014833"> <count>2</count> </nm> <nm id="773371838642"> <count>1</count> </nm> <nm id="763241653098"> <count>1</count> </nm> <nm id="728654070781"> <count>1</count> </nm> <nm id="760492014833"> <count>2</count> </nm> </liste>
内容的提问来源于stack exchange,提问作者Florian B.
相关产品推荐
相关产品推荐

