2012-12-19 106 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