類似於這個問題(有多個相關條目,但作爲一個新的用戶,我只能發佈一個URL): Xpath Get elements that are between 2 elements的XPath XSLT:選擇兩個其他元素之間的元素,第二部分
我對於選擇「其他/定界」元素之間出現的元素集有一個疑問。嘗試使用XSLT將平面HTML表格轉換爲層次結構的 時會出現這種情況。我嘗試在模板中使用遞歸,但撒克遜拒絕接受,因爲它導致死鎖,很可能是我的錯,但讓我們從頭開始。
第一源數據的HTML表:
<table >
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<th colspan="3" >Group 1</th>
</tr>
<tr>
<td>attribute 1.1.1</td>
<td>attribute 1.1.3</td>
<td>attribute 1.1.2</td>
</tr>
<tr>
<td>attribute 1.2.1</td>
<td>attribute 1.2.2</td>
<td>attribute 1.2.3</td>
</tr>
<tr>
<td>attribute 1.3.1</td>
<td>attribute 1.3.2</td>
<td>attribute 1.3.3</td>
</tr>
<tr>
<th colspan="3" >Group 2</th>
</tr>
<tr>
<td>attribute 2.1.1</td>
<td>attribute 2.1.3</td>
<td>attribute 2.1.2</td>
</tr>
<tr>
<td>attribute 2.2.1</td>
<td>attribute 2.2.2</td>
<td>attribute 2.2.3</td>
</tr>
<tr>
<td>attribute 2.3.1</td>
<td>attribute 2.3.2</td>
<td>attribute 2.3.3</td>
</tr>
</tbody>
</table>
XML中的目標輸出是:
<groups>
<group name="Group 1">
<item attribute1="attribute 1.1.1" attribute2="attribute 1.1.3" attribute3="attribute 1.1.2"/>
<item attribute1="attribute 1.2.1" attribute2="attribute 1.2.2" attribute3="attribute 1.2.3"/>
<item attribute1="attribute 1.3.1" attribute2="attribute 1.3.2" attribute3="attribute 1.3.3"/>
</group>
<group name="Group 2">
<item attribute1="attribute 2.1.1" attribute2="attribute 2.1.3" attribute3="attribute 2.1.2"/>
<item attribute1="attribute 2.2.1" attribute2="attribute 2.2.2" attribute3="attribute 2.2.3"/>
<item attribute1="attribute 2.3.1" attribute2="attribute 2.3.2" attribute3="attribute 2.3.3"/>
</group>
</groups>
所以我想將所有的項目條目,(TR元素)和將它們添加到一個組中。這基本上歸結爲選擇所有後續兄弟TR元素,直到我們遇到一個具有TH元素作爲孩子的元素。如果我只能確定有TH孩子,表示爲一組一個新的標題這個第一TR的位置,這可能是與完成:
<xsl:for-each select="tbody/tr">
<xsl:if test="th">
<xsl:element name="group">
<xsl:attribute name="name"><xsl:value-of select="th"/></xsl:attribute>
<xsl:for-each select="following-sibling::tr[position() < $positionOfNextThElement]">
<xsl:call-template name="item"/>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:for-each>
不過,我不能確定的位置首先遇到TR/TH標籤。
如上所述,我嘗試使用模板中的遞歸:總是調用「item」模板,並在此模板中確定是否要在下一個項目上調用它。我認爲問題出在模板中調用模板。上下文中的項目不會增加?我應該交出一個參數來確定我們正在處理的項目嗎?
總之,這是我想出了:
<xsl:for-each select="tbody/tr">
<xsl:if test="th">
<xsl:element name="group">
<xsl:attribute name="name"><xsl:value-of select="th"/></xsl:attribute>
<xsl:call-template name="item"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
<xsl:template name="item">
<xsl:element name="item">
<xsl:attribute name="attribute1"><xsl:value-of select="following-sibling::tr[1]/td[1]"/></xsl:attribute>
<xsl:attribute name="attribute2"><xsl:value-of select="following-sibling::tr[1]/td[2]"/></xsl:attribute>
<xsl:attribute name="attribute2"><xsl:value-of select="following-sibling::tr[1]/td[3]"/></xsl:attribute>
</xsl:element>
<!-- When the next element has not got a TH tag, continue with invoking this template -->
<xsl:if test="count(following-sibling::tr[1]/th) != 1">
<xsl:call-template name="item"/>
</xsl:if>
</xsl:template>
就如何實現這一歡迎任何建議!
豎起大拇指爲您的答案!這樣做的好處是,所幸屬性的數量是靜態的。我將查看參考文檔,以瞭解將來的分組問題。 – Holtkamp 2009-10-10 15:11:18