2016-02-25 80 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