RE: [xsl] Help with moving nodes from one tag to a new

Subject: RE: [xsl] Help with moving nodes from one tag to a new
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 3 Jan 2008 11:08:14 -0000
It's very easy to code this specific transformation for this particular data
set. The challenge is to cope with the variability that might arise in the
input, and you haven't really given any clues as to how much variability you
want to handle.

One could imagine a stylesheet that takes as input a set of prefixes (RC,
FG) and then groups adjacent elements if their names start with the same one
of these prefixes. In XSLT 2.0 that would be (untested!)

<xsl:variable name="prefixes" as="xs:string" select="'RC', 'FG'"/>
<xsl:for-each-group select="*" 
  group-adjacent="((for $p in $prefixes return
                    if (starts-with(local-name(), $p))
                    then $p else ()), local-name())[1]">
  <xsl:choose>
    <xsl:when test="current-grouping-key() = $prefixes">
      <xsl:element name="{current-grouping-key()}">
        <xsl:for-each select="current-group()">
          <xsl:element name="{substring-after(local-name(),
current-grouping-key())}">
            <xsl:copy-of select="child::node()"/>
          </xsl:element>
        </xsl:for-each>
      </xsl:element>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="current-group()"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:for-each-group>

Michael Kay
http://www.saxonica.com/  

> -----Original Message-----
> From: David Larsson [mailto:laserallan@xxxxxxxxx] 
> Sent: 03 January 2008 10:48
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Help with moving nodes from one tag to a new
> 
> Hi!
> 
> Sorry for the somewhat confusing topic but this is what I'm 
> would like to accomplish.
> 
> When I designed an xml-format some time ago I made a mistake 
> organizing it like this:
> <Root>
>    <RandomTag1>data</RandomTag1>
>    <RCTest1>data</RCTest1>
>    <RCTest2>data</RCTest2>
>    <RCTest3>data</RCTest3>
>    <FGTest1>data</FGTest1>
>    <FGTest2>data</FGTest2>
>    <FGTest3>data</FGTest3>
>    <RandomTag2>data</RandomTag2>
>    <RandomTag3>data</RandomTag3>
> </Root>
> 
> I would like to use the following organization instead:
> <Root>
>    <RandomTag1>data</RandomTag1>
>    <RC>
>        <Test1>data</Test1>
>        <Test2>data</Test2>
>        <Test3>data</Test3>
>    </RC>
>    <FG>
>        <Test1>data</Test1>
>        <Test2>data</Test2>
>        <Test3>data</Test3>
>    </FG>
>    <RandomTag2>data</RandomTag2>
>    <RandomTag3>data</RandomTag3>
> </Root>
> 
> I wonder whether it would be possible to write an xsl 
> transform that does this particular transformation so I can 
> version check old files and transform them to the new format 
> for backward compatibility rather than support reading both 
> the old and the new format in my program.
> I'm not looking for some general solution that automatically 
> understands that RC and FG are two suitable prefix to create 
> a parent node for, this is something I can specify myself.
> I did some initial tests, but I realized that I don't know 
> enough xsl to do this kind of transformation, but if someone 
> can point me in the right direction (or perhaps convince me 
> that this kind of transform is not possible with xsl) I would 
> be very happy.
> 
> Regards
> /David Larsson

Current Thread