涉及属性的XSLT排序和分组



我有一个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>

我要做的是创建一个releasenotes文档,该文档首先对@field名称等于"release Version"的元素的所有唯一@field值进行排序和查找。可能还有其他元素不属于发布版本。这是我正在寻找的输出:

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"方法以及排序和分组的文章,但我很难理解这样一个事实,即我有需要比较的属性。我读过的大多数例子都讨论了元素排序,这似乎更直观。我需要对多个属性进行查找和排序,好吧,我的脑袋开始爆炸了。

我已经提出了样式表,它将为我提供所有以"Release Version"为文本的元素,使用:

<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"/>

但这给了我所有,而不仅仅是那些独特的。然后我还没有弄清楚如何获得包含我需要打印的发布说明的"event"元素。

当我尝试使用generate-id()时,我只得到一个结果,因为我想只有一个唯一的条目可以找到我的值:

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

使用当前密钥。。。

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

您将按字段名称对自定义字段值元素进行分组,如果您想查找不同的字段名称值,则可以这样做。但是,您希望按"发布版本"的字段值属性进行分组。这意味着你需要这样定义你的密钥:

<xsl:key name="keyMajorReleases" match="custom-field-value[@field-name='Release Version']" use="@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])]" />

然后,为了获得给定发布版本的发布说明,您可以再次使用密钥

<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>

最新更新