2013-02-13 91 views
3

我想要從XML轉換爲結合了一些元素的文本,但避免了輸出中的重複。 的XML將是類似的東西:XSLT:組合元素不重複

<A> 
    <B> 
    <param1>value0</param1> 
    <param2>value1</param2> 
    </B> 
    <B> 
    <param1>value2</param1> 
    <param2>value3</param2> 
    </B> 
    <C> 
    <param3>valueC1</param3> 
    <D> 
     <param4>value0</param4> 
     <param5>value4</param5> 
    </D> 
    <D> 
     <param4>value0</param4> 
     <param5>value5</param5> 
    </D> 
    <D> 
     <param4>value2</param4> 
     <param5>value6</param5> 
    </D> 
    </C> 
    <C> 
    <param3>valueC2</param3> 
    <D> 
     <param4>value0</param4> 
     <param5>value5</param5> 
    </D> 
    </C> 
</A> 

和輸出:

OBJECT: param1=value0, param2=value1, param3=valueC1, param4=value0; 
OBJECT: param1=value2, param2=value3, param3=valueC1, param4=value2; 
OBJECT: param1=value0, param2=value1, param3=valueC2, param4=value0; 

注:

  • 對於每個d對象,請使用D.乙對象比賽param4 = B.param1
  • 如果有兩個或多個D對象放入同一個C並且與相同的B匹配,則只打印其中的一個(在本例中爲noth因爲它會產生與第一個D對象相同的行)
  • 如果有兩個D對象與相同的B匹配,但是分配到不同的C,則同時打印兩個(輸出示例中的第三行)

我找了一些類似的問題,但我找不到任何相同的情況。

我想這可以通過使用鍵來完成,但它太複雜了。

謝謝!

Regards, Ale。

PS:對不起,我的英語。

+0

哪裏了'param4 = value1'第二排從何而來?那應該是'價值2'嗎? – 2013-02-13 11:17:45

+0

是的,這是值2,對不起。 – user2067923 2013-02-13 11:37:52

回答

3

既然你沒有將你的輸出任何使用param5這似乎是可以簡化問題

  • 關於C
    • 找到所有不同乙元素,其param1param4的任何所包含的Ds
    • 對於這些中的每一個
      • 提取物B /參數1,B/param2的,currentC /參數3,B /參數1再次(但標記param4)

這是實現一種方法,使用的模板。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="text" /> 
    <xsl:key name="BbyParam1" match="B" use="param1" /> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="A/C" /> 
    </xsl:template> 

    <xsl:template match="C"> 
    <xsl:apply-templates select="key('BbyParam1', D/param4)"> 
     <xsl:with-param name="currentC" select="." /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="B"> 
    <xsl:param name="currentC" /> 
    <xsl:text>OBJECT: param1=</xsl:text> 
    <xsl:value-of select="param1" /> 
    <xsl:text>, param2=</xsl:text> 
    <xsl:value-of select="param2" /> 
    <xsl:text>, param3=</xsl:text> 
    <xsl:value-of select="$currentC/param3" /> 
    <xsl:text>, param4=</xsl:text> 
    <xsl:value-of select="param1" /> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 

「找到所有不同乙元件,其param1匹配的所包含的D的任何param4」實際上是非常簡單的,由於這樣的事實:當你經過設置爲第二參數的一個節點key函數它正是這樣做的 - 它返回所有節點的集合,其中的鍵值是參數節點集中節點的任意的字符串值,並且返回的節點集(作爲集合)保證不包含重複項。

+0

它工作正常,它很容易理解:)非常感謝你! – user2067923 2013-02-13 17:51:39

0

這應該做的伎倆:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" indent="yes"/> 
    <xsl:key name="kB" match="B" use="param1" /> 
    <xsl:key name="kD" match="D" 
      use="concat(param4, '+', generate-id(..))"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="A/C" /> 
    </xsl:template> 

    <xsl:template match="C"> 
    <xsl:apply-templates select="D[key('kB', param4) and 
            generate-id() = 
            generate-id(key('kD', 
             concat(
              param4, 
              '+', 
              generate-id(..) 
             ) 
            )[1])]" /> 
    </xsl:template> 

    <xsl:template match="D"> 
    <xsl:value-of 
     select="concat('OBJECT: param1=', 
        key('kB', param4)/param1, 
        ', param2=', 
        key('kB', param4)/param2, 
        ', param3=', 
        ../param3, 
        ', param4=', 
        param4, 
        '&#xA;')"/> 
    </xsl:template> 
</xsl:stylesheet> 

輸出,當你的樣品運行:

OBJECT: param1=value0, param2=value1, param3=valueC1, param4=value0 
OBJECT: param1=value2, param2=value3, param3=valueC1, param4=value2 
OBJECT: param1=value0, param2=value1, param3=valueC2, param4=value0 
+0

看到伊恩羅伯茨的解決方案後,我認爲他是更好的,雖然:) – JLRishe 2013-02-13 11:40:16

+0

謝謝:)總是很高興得到專家的信任投票。 – 2013-02-13 11:42:06

+0

謝謝你的回答:) – user2067923 2013-02-13 17:52:50