xml - 涉及属性的 XSLT 排序和分组

标签 xml sorting xslt grouping

我有一个类似于此示例的 XML 文件:

<Data>
  <defect>
    <record-id>1</record-id>
    <custom-field-value field-name="Release Version" field-value="1.0"/>
    <custom-field-value field-name="Other info" field-value=""/>
    <custom-field-value field-name="More info" field-value="blah"/>

    <event include-in-release-notes="yes">
      <notes>This is a release note to include</notes>
    </event>

    <event include-in-release-notes="no">
      <notes>This is not a release note</notes>
    </event>
  </defect>

  <defect>
    <record-id>2</record-id>
    <custom-field-value field-name="Release Version" field-value="1.5"/>
    <custom-field-value field-name="Other info" field-value=""/>
    <custom-field-value field-name="More info" field-value="blah"/>

    <event include-in-release-notes="yes">
      <notes>This is a release note to include for 1.5</notes>
    </event>

    <event include-in-release-notes="no">
      <notes>This is not a release note</notes>
    </event>
  </defect>
</Data>

我想做的是创建一个发行说明文档,该文档首先排序并查找@field-name 等于“发布版本”的元素的所有唯一@field-value 值。可能还有其他与发布版本无关的元素。这是我正在寻找的输出:

Release Version: 1.0
  o This is a release note to include
Release Version: 1.5
  o This is a release note to include for 1.5
Release Verison: x.x
  o one release note
  o another release note

我已经阅读了很多关于“Muenchian”方法以及排序和分组的内容,但我正在努力解决我需要比较的属性这一事实。我读过的大多数例子都讨论了对元素的排序,这似乎更直观。而且我需要查找多个属性并对其进行排序,好吧,我的脑袋开始爆炸了。

我想出了一个样式表,它将给我所有具有“发布版本”作为文本的元素,使用:

<xsl:key name="keyMajorReleases" match="custom-field-value" use="@field-name"/>
<xsl:for-each select=key('keyMajorReleases', 'Release Version')">
  <xsl:sort order="descending" data-type="text" select="@field-value"/>

但这给了我全部,而不仅仅是独特的。然后我还没有弄清楚如何获取具有我需要打印的发行说明的“事件”元素。

当我尝试使用“generate-id()”时,我只得到一个结果,因为我猜只有一个具有我的值的唯一条目可供查找:

<xsl:for-each select="//custom-field-value[generate-id(.)=generate-id(key('keyMajorReleases', 'Release Version')[1])]">

最佳答案

使用您当前的 key ...

<xsl:key name="keyMajorReleases" match="custom-field-value" use="@field-name"/>

您可以按字段名对 custom-field-value 元素进行分组,如果您想找到不同的字段名值,您会这样做。但是,您希望按“发布版本”的字段值属性进行分组。这意味着您需要像这样定义 key :

<xsl:key name="keyMajorReleases" match="custom-field-value[@field-name='Release Version']" use="@field-value"/>

使用此键,您仅匹配 custom-field-value,其中字段名称为“Release Version”。然后您可以使用它来获取不同的字段值属性,如下所示:

<xsl:apply-templates 
     select="defect/custom-field-value[@field-name='Release Version']
         [generate-id()=generate-id(key('keyMajorReleases', @field-value)[1])]" />

然后要获取给定发行版本的发行说明,您可以再次使用该 key

<xsl:apply-templates 
   select="key('keyMajorReleases', @field-value)
        /following-sibling::event[@include-in-release-notes='yes']" />

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="keyMajorReleases" match="custom-field-value[@field-name='Release Version']" use="@field-value"/>
   <xsl:template match="/Data">
      <ul>
         <xsl:apply-templates select="defect/custom-field-value[@field-name='Release Version'][generate-id()=generate-id(key('keyMajorReleases', @field-value)[1])]"/>
      </ul>
   </xsl:template>

   <xsl:template match="custom-field-value">
      <li>Release Version: <xsl:value-of select="@field-value"/>
         <ul>
            <xsl:apply-templates select="key('keyMajorReleases', @field-value)/following-sibling::event[@include-in-release-notes='yes']"/>
         </ul></li>
   </xsl:template>

   <xsl:template match="event">
      <li>
         <xsl:value-of select="notes"/>
      </li>
   </xsl:template>
</xsl:stylesheet>

应用于示例 XML 时,输出如下

<ul>
   <li>Release Version: 1.0
       <ul>
          <li>This is a release note to include</li>
       </ul>
   </li>
   <li>Release Version: 1.5
      <ul>
         <li>This is a release note to include for 1.5</li>
      </ul>
   </li>
</ul>

关于xml - 涉及属性的 XSLT 排序和分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13960791/

相关文章:

C# - 仅按父节点对 TreeView 进行排序

xml - 逻辑应用 - XML 转换 - 禁止执行 'document()' 函数?

c# - 如何在xml元素内添加冒号? Linq to xml C#

c - 如何将结构的成员与冒泡排序保持在一起?

ios - 无法在我的 iOS 应用程序中读取 XML 文件

javascript - jQuery 使用数据 id 对元素进行排序

xml - 在 XSLT 中,如何从不同的范围递增全局变量?

XSLT 跨节点和文本排序

java - 针对具有相同命名空间的两个模式验证 Java 中的 XML 文件

xml - 抓取此 URL、R XML 并获取 sibling