2012-04-17 40 views
0

我正在嘗試使用XSLT編寫一個循環,以便使用相同的ID自動分組所有項目,但以不區分大小寫的方式。不幸的是,我試圖解析的數據是客戶端驅動的,所以我無法在加載之前對其進行更改。 不管這裏是一個XML結構...xslt包裝重複行不區分大小寫內容爲每個

<Document> 
    <Row> 
     <Cell>ID</Cell> 
    </Row> 
    <Row> 
     <Cell>hi</Cell> 
    </Row> 
    <Row> 
     <Cell>Hi</Cell> 
    </Row> 
    <Row> 
     <Cell>Hello</Cell> 
    </Row> 
    <Row> 
     <Cell>Hello</Cell> 
    </Row> 
    <Row> 
     <Cell>Hola</Cell> 
    </Row> 
</Document> 

這是我目前使用XSLT ...

<xsl:template match="Document"> 
    <NewDocument xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:for-each select="//Row[position() &gt; 1]/Cell[1][not(.=preceding::Row/Cell[1])]"> 
     <xsl:variable name="currentOrderID" select="." /> 
     <xsl:variable name="currentOrderGroup" select="//Row[Cell[1] = $currentOrderID]" /> 

     <MainID> 
      <xsl:value-of select="$currentOrderGroup[1]/Cell[1]"/> 
     </MainID> 
     <IDs> 
      <xsl:for-each select="$currentOrderGroup"> 
      <id> 
       <xsl:value-of select="Cell[1]"/> 
      </id> 
      </xsl:for-each> 
     </IDs> 
     </xsl:for-each> 
    </NewDocument> 
    </xsl:template> 

這只是結束了事情,預計將在區分大小寫的方式.. 我一直試圖在那裏使用一個翻譯,以使所有內容都大寫,但是我似乎無法得到正確的語法。

我想在這裏實現的結果是這樣的:

<NewDocument> 
    <MainID>hi</MainID> 
    <IDs> 
    <id>hi</id> 
    <id>Hi</id> 
    </IDs> 
    <MainID>Hello</MainID> 
    <IDs> 
    <id>Hello</id> 
    <id>Hello</id> 
    </IDs> 
    <MainID>Hola</MainID> 
    <IDs> 
    <id>Hola</id> 
    </IDs> 
</NewDocument> 

似乎無法找到任何專門針對我需要什麼。 謝謝!

+0

好像將是你的朋友在這裏。 – 2012-04-17 21:14:51

回答

2

在XSLT1.0中,要將字符串轉換爲小寫字母,您需要使用較爲繁瑣的translate在xpath中的函數。

translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') 

此外,你的問題是分組中的一個,並在XSLT1.0這通常意味着稱爲Meunchian分組的技術。要做到這首先要定義鍵查找項目的團體,你需要

<xsl:key 
    name="Cell" 
    match="Cell" 
    use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/> 

在這裏,我們尋找了基於他們(小寫)文本內容的單元格。

要找到的第一個元素的每個組中,你看細胞中的XML這也恰好是發生在你的查找關鍵的第一要素

<xsl:apply-templates 
    select="Row/Cell 
    [generate-id() 
    = generate-id(
     key('Cell', 
     translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/> 

然後,當你匹配元素第一個元素,您可以通過查看關鍵字來匹配組中的所有元素。

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="Cell" match="Cell" use="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/> 

    <xsl:template match="Document"> 
     <NewDocument> 
     <xsl:apply-templates select="Row/Cell[generate-id() = generate-id(key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))[1])]"/> 
     </NewDocument> 
    </xsl:template> 

    <xsl:template match="Cell"> 
     <MainID> 
     <xsl:value-of select="."/> 
     </MainID> 
     <IDs> 
     <xsl:apply-templates select="key('Cell', translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))" mode="group"/> 
     </IDs> 
    </xsl:template> 

    <xsl:template match="Cell" mode="group"> 
     <id> 
     <xsl:value-of select="."/> 
     </id> 
    </xsl:template> 
</xsl:stylesheet> 

注意使用模式屬性的,兩個模板匹配細胞元件之間進行區分。

當適用於您的XML,下面是輸出:

<NewDocument> 
    <MainID>ID</MainID> 
    <IDs> 
     <id>ID</id> 
    </IDs> 
    <MainID>hi</MainID> 
    <IDs> 
     <id>hi</id> 
     <id>Hi</id> 
    </IDs> 
    <MainID>Hello</MainID> 
    <IDs> 
     <id>Hello</id> 
     <id>Hello</id> 
    </IDs> 
    <MainID>Hola</MainID> 
    <IDs> 
     <id>Hola</id> 
    </IDs> 
</NewDocument> 

注意,我不知道做什麼用的細胞與ID作爲一種價值,所以我離開了進去。如果你想排除它,只需添加此行到XSLT

<xsl:template match="Cell[. = 'ID']" /> 
+0

這是完美的謝謝! – John 2012-04-18 02:45:18

+0

此外,我只是想跳過第一行,因爲它有與負載無關的數據。所以在這樣做的時候,我只是把主調用改成了'',它就像一個冠軍。 – John 2012-04-18 02:47:49