要做的第一件事就是將源XML轉換爲適當的形式。
XML文檔包含只有一個根標籤(讓我們稱之爲主) 和該標籤可以包含多個源代碼(例如,對象)。
每個標籤(如你在串寫標籤)可以包含屬性有值 (在你的情況名和爲了),但它們之間必須是「=」標誌。
在對象標籤的情況下,你記得把在「/」關閉標籤, 但你在每個關串標籤忘了。
所以正確的輸入XML(需要更正後)爲:
<main>
<object>
<string name="order">1</string>
<string name="item">1</string>
</object>
<object>
<string name="order">1</string>
<string name="item">2</string>
</object>
<object>
<string name="order">2</string>
<string name="item">1</string>
</object>
</main>
現在讓我們倒在主業。 在描述中我把行號 - 引用到最終的解決方案。
我們從xsl:輸出indent =「是」(第2行)開始,否則所有內容 將在單行(難以閱讀)中。
該XML代碼包含單個tempate匹配主要標記(第4行)。
它所做的第一件事是拷貝(開啓和關閉主標籤 - 第5行)。
然後,第6行包含分組循環(,針對每個組)。細分電子郵件廣告是對象元素中的對象(參見選擇子句)和分組關鍵是串子標籤的含量(相對於當前對象)與屬性名稱等於「命令」(見組 - 由子句)。
所以第一組包含對象標籤號1和2(它們都具有 字符串名稱=「順序」標籤用的「1」的內容和所述第二組包含 對象標籤號3。
然後(對於每組源對象標籤)
我們創建輸出對象元件(第7行),該元件必須具有一個ATT ribute命名爲order與當前分組鍵(第8行)的值爲 。
當前元素(輸出對象)是包含在 當前組從每個元素數據,所以我們必須寫的for-each語句,通過 所有源循環對象標籤 - 的含量(請參閱選擇子句,第9行)。
在此循環中,對於每個輸入對象,我們創建了一個字符串元素(第10行)。
這個元素有一個名爲「名」的屬性(見名條款)和 其值應爲「項目」(見選擇條款) - 行11
的最後一件事要做的就是創建輸出標籤的內容 - 與 屬性的名項目值 價值孩子串標籤的(相對於當前對象) - 行12
XSL中的所有其他行都是結束標記。
下面有一個完整的XSL解決方案。
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="main">
<xsl:copy>
<xsl:for-each-group select="object" group-by="string[@name='order']">
<xsl:element name="object">
<xsl:attribute name="order" select="current-grouping-key()"/>
<xsl:for-each select="current-group()">
<xsl:element name="string">
<xsl:attribute name="name" select="'item'"/>
<xsl:value-of select="string[@name='item']"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>
這是*分組*問題。做一個搜索 - 這可能是最經常被問到的XSLT問題。請注意,對於XSLT 1.0或2.0,答案是不同的。 –