2016-02-25 70 views
0

xslt這裏的另一個新手。我有一個類似於這個問題 - Applying Muenchian grouping for a simple XML with XSLT - 但由一個額外的節點層複雜。稍微複雜一點xslt muenchian分組

我有這個XML ...

<ALLDATA> 
    <THIS> 
    <ID>datum 1</ID> 
    <DATA>datarecord1</DATA> 
    <RELATIONSHIPS> 
     <rel> 
     <relid>rd1</relid> 
     <reldata>something</reldata> 
     </rel> 
    </RELATIONSHIPS> 
    </THIS> 
    <THIS> 
    <ID>datum 1</ID> 
    <DATA>datarecord1</DATA> 
    <RELATIONSHIPS> 
     <rel> 
     <relid>rd2</relid> 
     <reldata>other</reldata> 
     </rel> 
    </RELATIONSHIPS> 
    </THIS> 
    <THIS> 
    <ID>rd1</ID> 
    <DATA>relrecord1</DATA> 
    <RELATIONSHIPS/> 
    </THIS> 
    <THIS> 
    <ID>rd2</ID> 
    <DATA>relrecord2</DATA> 
    <RELATIONSHIPS/> 
    </THIS> 
</ALLDATA> 

...並想將它轉換成...

<ALLDATA> 
    <THIS> 
    <ID>datum 1</ID> 
    <DATA>datarecord1</DATA> 
    <RELATIONSHIPS> 
     <rel> 
     <relid>rd1</relid> 
     <reldata>something</reldata> 
     </rel> 
     <rel> 
     <relid>rd2</relid> 
     <reldata>other</reldata> 
     </rel> 
    </RELATIONSHIPS> 
    </THIS> 
    <THIS> 
    <ID>rd1</ID> 
    <DATA>relrecord1</DATA> 
    <RELATIONSHIPS/> 
    </THIS> 
    <THIS> 
    <ID>rd2</ID> 
    <DATA>relrecord2</DATA> 
    <RELATIONSHIPS/> 
    </THIS> 
</ALLDATA> 

我使用XSLT(1.0)顯然是道路關閉基地所以希望有人用更多的知識(你好!)可以幫助把我的權利:)

這裏是沒用的XSLT ...

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="krel" match="THIS" use="ID"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="appex_user/node"> 
    <xsl:copy> 
    <xsl:apply-templates select="THIS[generate-id() = generate-id(key('krel', ID)[1])]" mode="group"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="THIS/RELATIONSHIPS" mode="group"> 
    <xsl:copy> 
    <xsl:copy-of select="RELATIONSHIPS/rel"/> 
    <xsl:apply-templates select="key('krel', ID)"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

其實 - 我試過各種組合都無濟於事。

+0

好,'匹配= 「appex_user /節點」'不匹配任何您所張貼的輸入。 –

+0

爲了安全,不應該* DATA *也是關鍵的一部分?即使* ID *和* DATA *應該是一對一關聯的,也可能存在這樣一種情況,其中* THIS *元素具有相同的* ID *值,但具有不同的* DATA *值。然後在鍵上只運行* ID *的樣式表只會使用其中一個* DATA *元素,而其他具有不同值的其他元素將會丟失。只是說。 – xjuice

+0

Ach .. appex_user位來自原始位置 - 我調整了我的標記,使其看起來更通用,而不是使用真正的標記。 – rosensfole

回答

0

有幾件事情錯了你的XSLT

首先你有一個模板匹配「appex_user /節點」,這是不是在你的XML。你需要在這裏匹配根元素「ALLDATA」。

其次,在選擇不同的THIS元素時,使用「mode」屬性。沒有什麼不對,但是您沒有匹配使用模式的THIS元素的模板。這意味着XSLT將使用其默認模板,該模板不會輸出THIS元素,但繼續匹配其子元素。在這種情況下,我不認爲你真的需要使用「模式」。

現在,你確實有一個模板匹配RELATIONSHIPS使用模式,它將得到匹配,但是當你使用密鑰時,你使用它的值爲「ID」,它將查找一個名爲ID的元素作爲目前的RELATIONSHIPS節點。但是ID不是孩子。您應該使用表達式..\ID來獲取父節點的子節點。

試試這個XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="krel" match="THIS" use="ID"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="ALLDATA"> 
    <xsl:copy> 
    <xsl:apply-templates select="THIS[generate-id() = generate-id(key('krel', ID)[1])]" /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="THIS/RELATIONSHIPS"> 
    <xsl:copy> 
    <xsl:apply-templates select="key('krel', ../ID)/RELATIONSHIPS/rel"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
+0

謝謝蒂姆 - 看起來不錯。下週回去工作時我會放棄它:) – rosensfole

+0

除了我以前的回答 - 它工作得很好。再次感謝! – rosensfole