2012-05-18 111 views
0

我有源XML象下面這樣:結合同級XML標籤

<ROOT> 
    <RECORD> 
     <Tag1>Tag1 Value</Tag1> 
     <Tag2> 
      <TagA1>TagA1 Value</TagA1> 
      <TagA2>TagA2 Value</TagA2> 
      <TagA3>TagA3 Value</TagA3> 
     </Tag2> 
     <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
<RECORD> 
     <Tag1>Tag1 Value</Tag1> 
     <Tag2> 
      <TagA1>TagA1 Value</TagA1> 
      <TagA2>TagA2 Value</TagA2> 
     </Tag2> 
     <Tag1>Tag1 Value</Tag1> 
</RECORD> 
</ROOT> 

我需要到像下面::

<ROOT> 
    <RECORD> 
     <Tag1>Tag1 Value</Tag1> 
     <Tag2>TagA1 Value | TagA2 Value | TagA3 Value</Tag2> 
     <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
<RECORD> 
     <Tag1>Tag1 Value</Tag1> 
     <Tag2>TagA1 Value | TagA2 Value</Tag2> 
     <Tag1>Tag1 Value</Tag1> 
</RECORD> 
</ROOT> 

我必須得到原始XML以這種形式,我們如何才能做到這使用XSLT?

回答

0

另外一個變化(使用已經提出的想法,但是,我認爲,最簡單的方法,不使用<xsl:for-each>):

XSLT:

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

    <!-- Identity Template: copies everything as-is --> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- For all grandchildren of <RECORD> elements, concat them, using --> 
    <!-- a pipe as a delimiter (as long as we're not on the last element) --> 
    <xsl:template match="RECORD/*/*"> 
    <xsl:value-of select="." /> 
    <xsl:if test="position() != last()"> 
     <xsl:text> | </xsl:text> 
    </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

輸入XML:

<?xml version="1.0" encoding="UTF-8"?> 
<ROOT> 
    <RECORD> 
    <Tag1>Tag1 Value</Tag1> 
    <Tag2> 
     <TagA1>TagA1 Value</TagA1> 
     <TagA2>TagA2 Value</TagA2> 
     <TagA3>TagA3 Value</TagA3> 
    </Tag2> 
    <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
    <RECORD> 
    <Tag1>Tag1 Value</Tag1> 
    <Tag2> 
     <TagA1>TagA1 Value</TagA1> 
     <TagA2>TagA2 Value</TagA2> 
    </Tag2> 
    <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
</ROOT> 

OUTPUT:

<?xml version="1.0" encoding="UTF-8"?> 
<ROOT> 
    <RECORD> 
    <Tag1>Tag1 Value</Tag1> 
    <Tag2>TagA1 Value | TagA2 Value | TagA3 Value</Tag2> 
    <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
    <RECORD> 
    <Tag1>Tag1 Value</Tag1> 
    <Tag2>TagA1 Value | TagA2 Value</Tag2> 
    <Tag1>Tag1 Value</Tag1> 
    </RECORD> 
</ROOT> 
1

這裏有一個可能性,以產生所需的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template>  

    <xsl:template match="RECORD/*[*]"> 
    <xsl:copy> 
     <xsl:for-each select="*"> 
     <xsl:value-of select="."/> 
     <xsl:if test="position() != last()"> | </xsl:if> 
     </xsl:for-each> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
1

我認爲你可以做到這一點我有一個模板來匹配記錄元素的「盛大孩子的節點,只需outputing值。例如,

<xsl:template match="RECORD/*/*"> 
    <xsl:value-of select="." /> 
</xsl:template> 

不管怎樣,您需要第一個和後續節點的不同情況,以處理|他們之間的性格。試試這個XSLT作爲替代

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

    <xsl:template match="RECORD/*/*[1]"> 
     <xsl:value-of select="." /> 
    </xsl:template> 

    <xsl:template match="RECORD/*/*[position() > 1]"> 
     <xsl:value-of select="concat(' | ', .)" /> 
    </xsl:template> 

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