Re: [xsl] xml to xml transform

Subject: Re: [xsl] xml to xml transform
From: Mike Brown <mike@xxxxxxxx>
Date: Mon, 15 Jan 2001 20:54:00 -0700 (MST)
Shimon Pozin wrote:
> How can I transform document:
> <row @fld="f1" value="v1">
> <row @fld="f1" value="v2">
> <row @fld="f2" value="v3">
> <row @fld="f3" value="v4">

This isn't even XML.
I will answer your question based on the assumption that you meant:

<row fld="f1" value="v1"/>
<row fld="f1" value="v2"/>
<row fld="f2" value="v3"/>
<row fld="f3" value="v4"/>

> to
> <f1>
> <v1/>
> <v2/>
> </f1>
> <f2>
> <v3/>
> </f2>
> <f3>
> <v4/>
> </f3>
> if I don't know values f1, f2, etc. in advance?

This is a fun (fun in a pathetically geeky way) variation on the grouping
FAQ. There is a design pattern for this. In your case it is along the
lines of the following:

  1. id a node-set representing the unique values from all the @fld
       attributes (one f1, one f2, one f3...). create an element with
       a name that is the same as the value. in the content of that
  2. iterate through that set, finding the rest of the @fld values that
       have the current value (all f1s, all f2s, all f3s...). There's your
       group. All you have to do is...
  3. Iterate through those (or in this case, through the corresponding
       @value attributes) and create elements named for their values.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl=""; version="1.0">

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

        <xsl:template match="rows">
           <xsl:for-each select="row[not(@fld = preceding-sibling::row/@fld)]"> 
              <xsl:element name="{@fld}">
                 <xsl:for-each select="../row[@fld = current()/@fld]">
                    <xsl:element name="{@value}"/>


   - Mike
Mike J. Brown, software engineer at            My XML/XSL resources: in Denver, Colorado, USA    

 XSL-List info and archive:

Current Thread