xml - Merge specific elements but keep document order using XSLT 1.0 -


given following document:

<doc>   <a>a</a>   <b>1</b>   <b>2</b>   <b>3</b>   <c>c</c> </doc> 

i want turned into:

<doc>   <a>a</a>   <b>1,2,3</b>   <c>c</c> </doc> 

what have far (mostly taken post here @ so):

<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="doc">     <xsl:copy>       <xsl:apply-templates select="*[not(self::b)]"/>       <b><xsl:apply-templates select="b/text()"/></b>     </xsl:copy>   </xsl:template>    <xsl:template match="b/text()">     <xsl:if test="position() &gt; 1">,</xsl:if>     <xsl:value-of select="."/>   </xsl:template>  </xsl:stylesheet> 

this creates following result:

<doc><a>a</a><c>c</c><b>1,2,3</b></doc> 

but i'm struggling find solution keeps document order intact. run of <b> elements should replaced single element containing text of original elements comma separated list. other elements should not reordered.

you can use sibling recursion in different mode:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"     version="1.0">      <xsl:output indent="yes"/>     <xsl:strip-space elements="*"/>      <xsl:template match="node()|@*">         <xsl:copy>             <xsl:apply-templates select="node()|@*" />         </xsl:copy>     </xsl:template>      <xsl:template match="b[not(preceding-sibling::*[1][self::b])]">         <xsl:copy>             <xsl:apply-templates select="." mode="merge"/>         </xsl:copy>     </xsl:template>      <xsl:template match="b[preceding-sibling::*[1][self::b]]"/>      <xsl:template match="b" mode="merge">         <xsl:value-of select="."/>         <xsl:variable name="next" select="following-sibling::*[1][self::b]"/>         <xsl:if test="$next">             <xsl:text>,</xsl:text>             <xsl:apply-templates select="$next" mode="merge"/>         </xsl:if>     </xsl:template>  </xsl:stylesheet> 

Comments

Popular posts from this blog

sql - invalid in the select list because it is not contained in either an aggregate function -

Angularjs unit testing - ng-disabled not working when adding text to textarea -

How to start daemon on android by adb -