好的,我想应用一个XSL样式表来计算以前唯一的“ROLE”节点,并将当前节点之前的唯一ROLE节点数量的@name输出格式.我浪费了几个小时才能实现一件容易的事情.我试图用几种方法实现这个,包括Muenchian方法,if / with variables(不能增加变量),将模板应用到模板等都无济于事.
<ROLEACTIONINFO> <ROLE name="TESTER" /> <ROLE name="PARENT1"/> <ROLE name="PARENT1"/> <ROLE name="PARENT1"/> <ROLE name="PARENT2"/> <ROLE name="PARENT2"/> <ROLE name="PARENT3"/> <ROLE name="PARENT4"/> <ROLE name="TESTROLE"/> </ROLEACTIONINFO>
输出示例:
TESTER 1 PARENT1 2 PARENT1 2 PARENT1 2 PARENT2 3 PARENT2 3 PARENT3 4 PARENT4 5 TESTROLE 6
获取唯一的前置节点的计数是我的问题.任何帮助,将不胜感激
解决方法
使用XPath可以很容易地解决这个问题.这是你正在寻找的表达式:count((.| preceding-sibling :: ROLE)[not(@name = preceding-sibling :: ROLE / @ name)])
这可以分解为使其更具可读性,正如我在以下XSLT 1.0样式表中所做的那样:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <!-- don't copy whitespace --> <xsl:template match="text()"/> <xsl:template match="ROLE"> <xsl:variable name="roles-so-far" select=". | preceding-sibling::ROLE"/> <!-- Only select the first instance of each ROLE name --> <xsl:variable name="roles-so-far-unique" select="$roles-so-far[not(@name = preceding-sibling::ROLE/@name)]"/> <xsl:apply-templates select="@name"/> <xsl:text> </xsl:text> <xsl:value-of select="count($roles-so-far-unique)"/> <xsl:text>
</xsl:text> <!-- lineFeed --> </xsl:template> </xsl:stylesheet>
这是使用Muenchian方法的替代实现.首先,声明一个键:
<xsl:key name="roles" match="ROLE" use="@name"/>
然后,用以下内容替换$roles-so-far-unique的定义:
<!-- Among all the ROLEs having one of the names so far,select only the first one for each name --> <xsl:variable name="roles-so-far-unique" select="../ROLE[@name = $roles-so-far/@name] [generate-id(.) = generate-id(key('roles',@name)[1])]"/>
当然,这段代码更复杂.除非你有一个大型数据集要求你使用Muenchian方法加速处理(即使那时我会测试以确保它能为你买任何东西),你也可以坚持使用上面更简单的版本.
最后,在XSLT 2.0中,它更容易.使用以下内容简单地替换$roles-so-far-unique定义:
<!-- Return a list of distinct string values,with duplicates removed --> <xsl:variable name="roles-so-far-unique" select="distinct-values($roles-so-far/@name)"/>
我希望这可以帮助您确定您在提到的各种尝试中出错的位置.