Re: [xsl] Recursive wrapping

Subject: Re: [xsl] Recursive wrapping
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Thu, 13 Jul 2006 21:46:19 +0530
Hi Houman,
  This is an example of positional grouping.

Following is one solution to this problem:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">

<xsl:output method="xml" indent="yes" />

 <xsl:template match="/root">
   <root>
     <xsl:for-each select="*">
       <xsl:choose>
         <xsl:when test="not(self::Attribute)">
           <xsl:copy-of select="." />
         </xsl:when>
         <xsl:when test="not(preceding-sibling::*[1]/self::Attribute)">
           <OtherAttributes>
              <xsl:copy-of select="." />
              <xsl:call-template name="MakeGroup">
                <xsl:with-param name="nodeset"
select="following-sibling::*" />
              </xsl:call-template>
           </OtherAttributes>
         </xsl:when>
       </xsl:choose>
     </xsl:for-each>
   </root>
 </xsl:template>

 <xsl:template name="MakeGroup">
   <xsl:param name="nodeset" />

   <xsl:if test="$nodeset[1]/self::Attribute">
     <xsl:copy-of select="$nodeset[1]" />
     <xsl:call-template name="MakeGroup">
       <xsl:with-param name="nodeset" select="$nodeset[position() &gt; 1]" />
     </xsl:call-template>
   </xsl:if>
 </xsl:template>

</xsl:stylesheet>

For e.g., when the above stylesheet is applied to XML:

<root>
 <a>1</a>
 <b>2</b>
 <Attribute>
   <Name>xx</Name>
   <Value>xx</Value>
 </Attribute>
 <Attribute>
   <Name>yy </Name>
   <Value>yy</Value>
 </Attribute>
 <c>3</c>
</root>

The following output is produced:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <a>1</a>
  <b>2</b>
  <OtherAttributes>
     <Attribute>
        <Name>xx</Name>
        <Value>xx</Value>
     </Attribute>
     <Attribute>
        <Name>yy </Name>
        <Value>yy</Value>
     </Attribute>
  </OtherAttributes>
  <c>3</c>
</root>

Regards,
Mukul

On 7/13/06, Khorasani, Houman <Houman.Khorasani@xxxxxxxxxxxx> wrote:
Hi,

I have a problem, which should be quite straight forward but I can't
find the solution.


XML:


<a>1</a>
<b>2</b>
<Attribute>
       <Name>xx</Name>
       <Value>xx</Value>
</Attribute>
<Attribute>
       <Name>yy </Name>
       <Value>yy</Value>
</Attribute>
...
<c>3</c>



Would like to generate:
<a>1</a>
<b>2</b>
<OtherAttributes>
       <Attribute>
               <Name>xx</Name>
               <Value>xx</Value>
       </Attribute>
       <Attribute>
               <Name>yy </Name>
               <Value>yy</Value>
       </Attribute>
       ...
</OtherAttributes>
<c>3</c>

There could be 0 to n attribute elements and I would like to wrap them
between an OtherAttributes.

I have tried to solve it by recursive templates, but somehow I don't get
there.  Any suggestions?

Many thanks
Houman

Current Thread