加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml – XSL:计算以前唯一的兄弟姐妹

发布时间:2020-12-16 23:16:56 所属栏目:百科 来源:网络整理
导读:好的,我想应用一个XSL样式表来计算以前唯一的“ROLE”节点,并将当前节点之前的唯一ROLE节点数量的@name输出格式.我浪费了几个小时才能实现一件容易的事情.我试图用几种方法实现这个,包括Muenchian方法,if / with variables(不能增加变量),将模板应用到模板等
好的,我想应用一个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>

输出示例:

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>&#xA;</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)"/>

我希望这可以帮助您确定您在提到的各种尝试中出错的位置.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读