2012-07-11 41 views
0

的多次出現針對該XML CSV:XSLT:從XML生成具有標籤複雜的情況

<G> 
     <P> 
      <A> 
       <b>value b</b> 
       <c>value c</c> 
      </A> 
      <A> 
       <b>value b2</b> 
       <c>value c2</c> 
      </A> 
      <D>value ew</D> 
     <D>value e2</D>  
      <E>value f</E> 
     </P> 
     <P> 
      <A> 
       <b>value bx</b> 
       <c>value cx</c> 
      </A> 
      <A> 
       <b>value b2x</b> 
       <c>value c2x</c> 
      </A> 
      <D>value exw</D> 
     <D>value ex2</D> 

     <D>value ex2</D> 
      <E>value fx</E> 
     </P> 
    </G> 

像A和d標籤可以出現多次,上我的工作原XML有大量的標籤,其中許多有多個出現。 我不得不genetrate輸出爲:
值b      值c      值EW      值f
值b      值c      值E2      值f
值B2      值c2       value ew      值f
值B2      值C2      值E2      值f
值BX      值CX      值EXW      值fx
值BX      值cx      值EX2      值fx
值BX      值CX      值EX3      值fx
值B2X      值C2X      值EXW      值fx
值B2X      值c2x    個 值EX2      值fx
值B2X      值C2X      值EX3      值fx

這XSLT產生正確的輸出,如果一個標記有多個出現時但當其他標記像在上面的XML中重複這個不起作用。

<xsl:for-each select="//A"> 
    <xsl:value-of select="b"/> 
    <xsl:text>,</xsl:text> 
    <xsl:value-of select="c"/> 
    <xsl:text>,</xsl:text> 
    <xsl:value-of select="ancestor::P/D"/> 
    <xsl:text>,</xsl:text> 
    <xsl:value-of select="ancestor::P/E"/> 
    <xsl:text> 
</xsl:text> 
</xsl:for-each> 

請建議正確的XSLT

+0

難道這不是你昨天問同樣的問題? – Woody 2012-07-11 07:44:14

+0

實際的xml比我昨天使用的更加複雜(這只是解決方案的一部分),它更像這個,所以我在另一個問題中提出了這個問題,以便我可以更清楚地展示這個場景。 – user1484782 2012-07-11 08:12:17

回答

1

我認爲這可以通過對模板重複調用來實現。首先,你有一個模板匹配一個而是輸出bç元素,你將它們作爲參數,該d elemenet相匹配的模板

<xsl:template match="A"> 
    <xsl:apply-templates select="following-sibling::D"> 
    <xsl:with-param name="prefix"> 
     <xsl:value-of select="b"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="c"/> 
    </xsl:with-param> 
    </xsl:apply-templates> 
</xsl:template> 

然後,內與前綴匹配的模板,將前綴與D的值連接起來,並將其傳遞到與元素匹配的模板。

<xsl:template match="D"> 
    <xsl:param name="prefix"/> 
    <xsl:apply-templates select="following-sibling::E"> 
    <xsl:with-param name="prefix"> 
     <xsl:value-of select="$prefix"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="."/> 
    </xsl:with-param> 
    </xsl:apply-templates> 
</xsl:template> 

然後將Ë可以輸出整個字符串元素相匹配的模板。下面是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" indent="yes"/> 

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

    <xsl:template match="A"> 
     <xsl:apply-templates select="following-sibling::D"> 
     <xsl:with-param name="prefix"> 
      <xsl:value-of select="b"/> 
      <xsl:text>,</xsl:text> 
      <xsl:value-of select="c"/> 
     </xsl:with-param> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="D"> 
     <xsl:param name="prefix"/> 
     <xsl:apply-templates select="following-sibling::E"> 
     <xsl:with-param name="prefix"> 
      <xsl:value-of select="$prefix"/> 
      <xsl:text>,</xsl:text> 
      <xsl:value-of select="."/> 
     </xsl:with-param> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="E"> 
     <xsl:param name="prefix"/> 
     <xsl:value-of select="$prefix"/> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="."/> 
     <xsl:value-of select="'&#13;'"/> 
    </xsl:template> 
</xsl:stylesheet> 

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

value b,value c,value ew,value f 
value b,value c,value e2,value f 
value b2,value c2,value ew,value f 
value b2,value c2,value e2,value f 
value bx,value cx,value exw,value fx 
value bx,value cx,value ex2,value fx 
value bx,value cx,value ex2,value fx 
value b2x,value c2x,value exw,value fx 
value b2x,value c2x,value ex2,value fx 
value b2x,value c2x,value ex2,value fx 
1

這裏是一個可能的解決方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:variable name='s' select='","' /> 
    <xsl:template match="A"> 
     <xsl:variable name='b' select='b' /> 
     <xsl:variable name='c' select='c' /> 
     <xsl:for-each select="../D"><xsl:value-of select='$b' /><xsl:value-of select='$s' /><xsl:value-of select='$c' /><xsl:value-of select='$s' /><xsl:value-of select='.'/><xsl:value-of select='$s' /><xsl:value-of select='../E'/><xsl:text> 
</xsl:text></xsl:for-each> 
    </xsl:template> 
    <xsl:template match="text()" /> 
</xsl:stylesheet> 

注意,它看起來對所有A,併爲每個A輸出線A. 的每個d兄弟請注意,這是你想要的

它給出的輸出:

value b,value c,value ew,value f 
value b,value c,value e2,value f 
value b2,value c2,value ew,value f 
value b2,value c2,value e2,value f 
value bx,value cx,value exw,value fx 
value bx,value cx,value ex2,value fx 
value bx,value cx,value ex2,value fx 
value b2x,value c2x,value exw,value fx 
value b2x,value c2x,value ex2,value fx 
value b2x,value c2x,value ex2,value fx 
+0

這個解決方案對於這個特定的例子工作正常,但我想要一個更通用的解決方案,我的意思是,在我的情況下,有很多標籤可以出現多次。因此,如果在上述xl 也重複不止一次,沒有工作。 – user1484782 2012-07-11 07:58:11

+0

然後你可以使用相同的邏輯,並使用3個疊加的 – 2012-07-11 08:08:39