xsl to flatten xml nodes

Discussion in 'XML' started by Simon, Apr 12, 2004.

  1. Simon

    Simon Guest

    Hi,

    I have generated an xml document, and would like to be able to transform it
    to another such that the contents of a chosen node type are flattened (i.e.
    tags removed). e.g.

    <shop>
    <name>super</name>
    <sells>
    <drink>squash</drink>
    <drink>beer</drink>
    <food>
    <fresh>bread</fresh>
    <fresh>apples</fresh>
    <frozen>peas</frozen>
    </food>
    </sells>
    </shop>

    apply 'flatten' to <sells> to give...

    <shop>
    <name>super</name>
    <sells>
    squash
    beer
    bread
    apples
    peas
    </sells>
    </shop>

    This seems like the kind of thing I could use xsl for. Could someone please
    give me a xsl example showing how this would be done?

    Thanks for your time,
    Simon
     
    Simon, Apr 12, 2004
    #1
    1. Advertising

  2. Simon

    Simon Guest

    > This is quite straightforward. This transformation:
    >
    > <xsl:stylesheet version="1.0"
    > xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    >
    > <xsl:eek:utput omit-xml-declaration="yes" indent="yes"/>
    > <xsl:strip-space elements="*" />
    >
    > <xsl:template match="@* | node()">
    > <xsl:copy>
    > <xsl:apply-templates select="@* | node()"/>
    > </xsl:copy>
    > </xsl:template>
    >
    > <xsl:template match="*[ancestor::sells]">
    > <xsl:apply-templates/>
    > </xsl:template>
    >
    > <xsl:template match="text()[ancestor::sells]">
    > <xsl:value-of select="concat('
    ',.)"/>
    > </xsl:template>
    >
    > </xsl:stylesheet>


    Thanks for such a quick response! Is there any chance you could talk me
    through it so I fully understand how it works? My xsl book hasn't arrived
    yet!
    Thanks again,
    Simon
     
    Simon, Apr 12, 2004
    #2
    1. Advertising

  3. "Simon" <> wrote in message
    news:c5dpga$90t$...
    > Hi,
    >
    > I have generated an xml document, and would like to be able to transform

    it
    > to another such that the contents of a chosen node type are flattened

    (i.e.
    > tags removed). e.g.
    >
    > <shop>
    > <name>super</name>
    > <sells>
    > <drink>squash</drink>
    > <drink>beer</drink>
    > <food>
    > <fresh>bread</fresh>
    > <fresh>apples</fresh>
    > <frozen>peas</frozen>
    > </food>
    > </sells>
    > </shop>
    >
    > apply 'flatten' to <sells> to give...
    >
    > <shop>
    > <name>super</name>
    > <sells>
    > squash
    > beer
    > bread
    > apples
    > peas
    > </sells>
    > </shop>
    >
    > This seems like the kind of thing I could use xsl for. Could someone

    please
    > give me a xsl example showing how this would be done?



    This is quite straightforward. This transformation:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:eek:utput omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="@* | node()">
    <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="*[ancestor::sells]">
    <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="text()[ancestor::sells]">
    <xsl:value-of select="concat('
    ',.)"/>
    </xsl:template>

    </xsl:stylesheet>

    when applied on your source.xml:

    <shop>
    <name>super</name>
    <sells>
    <drink>squash</drink>
    <drink>beer</drink>
    <food>
    <fresh>bread</fresh>
    <fresh>apples</fresh>
    <frozen>peas</frozen>
    </food>
    </sells>
    </shop>

    produces the wanted result:

    <shop>
    <name>super</name>
    <sells>
    squash
    beer
    bread
    apples
    peas</sells>
    </shop>



    Cheers,

    Dimitre Novatchev [XML MVP],
    FXSL developer, XML Insider,

    http://fxsl.sourceforge.net/ -- the home of FXSL
    Resume: http://fxsl.sf.net/DNovatchev/Resume/Res.html
     
    Dimitre Novatchev [MVP XML], Apr 12, 2004
    #3
  4. Simon wrote:

    >>This is quite straightforward. This transformation:
    >>
    >><xsl:stylesheet version="1.0"
    >> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    >>
    >> <xsl:eek:utput omit-xml-declaration="yes" indent="yes"/>
    >> <xsl:strip-space elements="*" />
    >>
    >> <xsl:template match="@* | node()">
    >> <xsl:copy>
    >> <xsl:apply-templates select="@* | node()"/>
    >> </xsl:copy>
    >> </xsl:template>


    That template above is an identity transformation, it copies nodes from
    the source document to the result document.
    Many XSLT transformations use that template if much of the source
    document has to be copied over to the result document.
    Now you only need to write templates for those elements that are not to
    be copied.

    >> <xsl:template match="*[ancestor::sells]">
    >> <xsl:apply-templates/>
    >> </xsl:template>


    That template matches any element nodes whose ancestor is a <sells>
    element, that is your <drink> or <food> or <fresh> element. For those
    you don't want to copy the element but only their text content so all
    the template does is call xsl:apply-templates on the child nodes.

    >> <xsl:template match="text()[ancestor::sells]">
    >> <xsl:value-of select="concat('
    ',.)"/>
    >> </xsl:template>


    This template then deals with all the text nodes which have a <sells>
    element as an ancestor and outputs any of them on a line of its own.
    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Apr 12, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. gavnosis
    Replies:
    0
    Views:
    525
    gavnosis
    Aug 2, 2003
  2. delgados129
    Replies:
    2
    Views:
    564
    delgados129
    Apr 16, 2005
  3. Francis Avila
    Replies:
    0
    Views:
    471
    Francis Avila
    Nov 2, 2003
  4. th3dude
    Replies:
    0
    Views:
    433
    th3dude
    Jan 3, 2007
  5. Replies:
    2
    Views:
    395
    Steve Pope
    Sep 27, 2006
Loading...

Share This Page