2012-05-18 63 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>