【问题标题】:Find all nodes with an attribute value matching another查找属性值与另一个匹配的所有节点
【发布时间】:2013-10-26 05:59:09
【问题描述】:

我有一个看起来像这样的 pmd.xml 文件:

<file name="file1">
  <violation rule="rulename1" priority="1">
  </violation>
  <violation rule="rulename2" priority="2">
  </violation>
</file>
<file name="file2">
  <violation rule="rulename2" priority="2">
  </violation>
  <violation rule="rulename3" priority="1">
  </violation>
</file>

我正在使用 xslt 文件将其转换为另一个 xml 文件。

我现在尝试做的是: 对于优先级 = 1 的每个违规,计算整个 xml 中具有相同名称的违规数量。稍后使用 Prio=2 也是如此。

这样我就可以列出所有违规行为以及它们在文档中出现的频率,大致如下:

prio1:
rulename1, 1
rulename3, 1
prio2:
rulename2, 2

我找不到合适的 XPath 表达式来计算同名违规...

<xsl:for-each select="//violation[@priority = 1]">
<xsl:value-of select="count(???)"/>

有人有帮助的想法吗?

提前致谢!

【问题讨论】:

  • 您运行的是 XSLT 1.0 还是更高版本?
  • 我把定义改成了2.0,他没有抱怨,所以我觉得我用的是2.0 :)
  • 我只是想知道是否可以使用for-each-group。否则,我们会像在 Martin 的解决方案中那样使用 Muenchian 分组。您只是更改了定义还是安装了 XSLT 2.0?通常(使用 JDK)你只有 1.0。
  • 我认为这台机器上预装了 2.0。如果提供的不是太麻烦的话,我很想知道每个组的解决方案是什么样子的:)

标签: xml xslt xpath


【解决方案1】:

假设 XSLT 1.0 您可以使用键进行分组:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text"/>

<xsl:key name="k1" match="violation" use="@priority"/>
<xsl:key name="k2" match="violation" use="concat(@priority, '|', @rule)"/>

<xsl:template match="/">
  <xsl:apply-templates select="//violation[generate-id() = generate-id(key('k1', @priority)[1])]"/>
</xsl:template>

<xsl:template match="violation">
  <xsl:value-of select="concat('prio', @priority, ':&#10;')"/>
  <xsl:apply-templates select="key('k1', @priority)[generate-id() = generate-id(key('k2', concat(@priority, '|', @rule))[1])]" mode="rule"/>
</xsl:template>

<xsl:template match="violation" mode="rule">
  <xsl:value-of select="concat(@rule, ', ', count(key('k2', concat(@priority, '|', @rule))), '&#10;')"/>
</xsl:template>

</xsl:stylesheet>

变换

<files>
<file name="file1">
  <violation rule="rulename1" priority="1">
  </violation>
  <violation rule="rulename2" priority="2">
  </violation>
</file>
<file name="file2">
  <violation rule="rulename2" priority="2">
  </violation>
  <violation rule="rulename3" priority="1">
  </violation>
</file>
</files>

进入

prio1:
rulename1, 1
rulename3, 1
prio2:
rulename2, 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-07
    • 2022-07-22
    • 2018-04-20
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    相关资源
    最近更新 更多