好的,我想应用一个XSL样式表来计算以前唯一的"ROLE"节点,并将当前节点之前的唯一ROLE节点数量的@name输出格式.我浪费了几个小时才能实现一件容易的事情.我试图用几种方法实现这个,包括Muenchian方法,if/with variables(不能增加变量),将模板应用到模板等都无济于事.
我有以下XML:
<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>
Run Code Online (Sandbox Code Playgroud)
输出示例:
TESTER 1
PARENT1 2
PARENT1 2
PARENT1 2
PARENT2 3
PARENT2 3
PARENT3 4
PARENT4 5
TESTROLE 6
Run Code Online (Sandbox Code Playgroud)
获取唯一的前置节点的计数是我的问题.任何帮助,将不胜感激
使用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>
Run Code Online (Sandbox Code Playgroud)
这是使用Muenchian方法的替代实现.首先,声明一个键:
<xsl:key name="roles" match="ROLE" use="@name"/>
Run Code Online (Sandbox Code Playgroud)
然后,用以下内容替换$ 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])]"/>
Run Code Online (Sandbox Code Playgroud)
当然,这段代码更复杂.除非你有一个大型数据集要求你使用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)"/>
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助您确定您在提到的各种尝试中出错的位置.