2012-12-19 70 views
5

我有一个看起来像这个例子中的XML文件:XSLT排序和分组涉及属性

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

我试图做的是创建一个发行说明文档,首先排序和查找所有独特的@具有@字段名称的元素的字段值值等于“发布版本”。可能还有其他与发布版本无关的元素。下面是输出我在寻找:

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

但是,让他们在我身上,不只是唯一的个。然后,我还没有想出如何获得具有我需要打印的发行说明的'event'元素。

当我试图用“产生-ID()”,我只得到一个结果,因为我想只有一个与我的价值,唯一的入口发现:

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

回答

2

就您目前的关键...

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

通过此键,仅在自定义字段值其中字段名称是“发行版本”匹配。然后,您可以用它来得到不同的字段值的属性,就像这样:

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

蒂姆,感谢您的帮助!我没有意识到'key'和'select'中的语法用于指定一个等于某个值的特定属性。这是诀窍,再次感谢! – Gunn