XSL:计算以前的唯一兄弟姐妹 [英] XSL: Counting Previous Unique Siblings

查看:32
本文介绍了XSL:计算以前的唯一兄弟姐妹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,我想应用一个 XSL 样式表,它计算以前唯一的ROLE"节点并吐出以下输出格式 @name 当前节点之前的唯一 ROLE 节点的数量.我已经浪费了几个小时在应该很容易实现的事情上.我尝试通过多种方式实现这一点,包括 Muenchian 方法、if/with variables(无法增加变量)、将模板应用于模板等都无济于事.

OK, I want to apply a XSL style sheet that counts the previous unique "ROLE" nodes and spits out the following output format of @name the number of unique ROLE nodes prior to the current nodes. I've wasted several hours on what should be an easy thing to implement. I have tried to implement this in several ways including the Muenchian Method, if/with variables (Can't increment a variable), applying templates to templates etc to no avail.

我有以下 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>

输出示例:

TESTER  1
PARENT1 2
PARENT1 2
PARENT1 2
PARENT2 3
PARENT2 3
PARENT3 4
PARENT4 5
TESTROLE  6

获取唯一的前面节点的数量是我的问题.任何帮助将不胜感激

Getting the count of the unique preceeding nodes is my problem. Any help would be appreciated

推荐答案

使用 XPath 可以很容易地解决这个问题.这是您要查找的表达式:count((.|preceding-sibling::ROLE)[not(@name =preceding-sibling::ROLE/@name)])

This can be solved pretty easily using XPath. Here's the expression you're looking for: count((.|preceding-sibling::ROLE)[not(@name = preceding-sibling::ROLE/@name)])

这可以分解以使其更具可读性,正如我在以下 XSLT 1.0 样式表中所做的那样:

This can be broken down to make it more readable, as I've done in the following XSLT 1.0 stylesheet:

<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>&#xA;</xsl:text> <!-- linefeed -->
  </xsl:template>

</xsl:stylesheet>

这是使用 Muenchian 方法的替代实现.首先,声明一个键:

Here's an alternative implementation, using the Muenchian method. First, declare a key:

<xsl:key name="roles" match="ROLE" use="@name"/>

然后,用这样的东西替换 $roles-so-far-unique 的定义:

Then, replace the definition of $roles-so-far-unique with something like this:

<!-- 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 方法加速处理(即使那样我会测试以确保它能给你带来任何好处),你最好坚持使用上面的简单版本.

This code, of course, is more complicated. Unless you have a large data set requiring you to speed up processing using the Muenchian method (even then I would test to make sure it buys you anything), you might as well stick with the simpler version above.

最后,在 XSLT 2.0 中,这要容易得多.简单地将 $roles-so-far-unique 定义替换为以下内容:

Finally, in XSLT 2.0, it's much easier. Simple replace the $roles-so-far-unique definition with the following:

<!-- Return a list of distinct string values, with duplicates removed -->
<xsl:variable name="roles-so-far-unique"
              select="distinct-values($roles-so-far/@name)"/>

我希望这能帮助您确定在您提到的各种尝试中出错的地方.

I hope this has helped you identify where you went wrong in the various attempts that you mentioned.

这篇关于XSL:计算以前的唯一兄弟姐妹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆