XSL to flatten selective node in XML Doc

Discussion in 'XML' started by delgados129, Apr 15, 2005.

  1. delgados129

    delgados129 Guest

    I've seen a few XSL examples to flatten a specific node, but none that
    address this specific scenario:

    Given the following generic XML:

    <DocElement>
    <A attr="attribForA">TextForA</A>
    <B>TextForB</B>
    <C>
    <D>TextForD1</D>
    <E>TextForE1</E>
    </C>
    <C>
    <D>TextForD2</D>
    <E>
    <F>TextForF</F>
    </E>
    </C>
    </DocElement>

    XSL should transform it at a designated node (example <C>) and flatten
    any all all (all is important) children to the following:

    <DocElement>
    <A attr="attribForA">TextForA</A>
    <B>TextForB</B>
    <C_D>TextForD1</C_D>
    <C_E>TextForE1</C_E>
    <C_E_F>TextForF</C_E_F>
    <!-- Continue on in this fashion as deep as the tree goes -->
    </DocElement>


    I've struggled with dynamically creating the new elements as a "_"
    delimitted concatenation of all the child elements. Any and all help
    would be appreciated.

    Mario
     
    delgados129, Apr 15, 2005
    #1
    1. Advertising

  2. something like this:

    flat.xml
    ========

    <DocElement>
    <A attr="attribForA">TextForA</A>
    <B>TextForB</B>
    <C>
    <D>TextForD1</D>
    <E>TextForE1</E>
    </C>
    <C>
    <D>TextForD2</D>
    <E>
    <F>TextForF</F>
    </E>
    </C>
    </DocElement>



    flat.xsl
    ========

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


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

    <xsl:template match="*">
    <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="C">
    <xsl:apply-templates mode="a">
    <xsl:with-param name="x" select="'C'"/>
    </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="*" mode="a">
    <xsl:param name="x"/>
    <xsl:if test="text()">
    <xsl:element name="{$x}_{name()}">
    <xsl:value-of select="text()"/>
    </xsl:element>
    </xsl:if>
    <xsl:apply-templates mode="a" select="*">
    <xsl:with-param name="x" select="concat($x,'_',name())"/>
    </xsl:apply-templates>
    </xsl:template>

    </xsl:stylesheet>






    $ saxon flat.xml flat.xsl
    <?xml version="1.0" encoding="utf-8"?>
    <DocElement>
    <A attr="attribForA">TextForA</A>
    <B>TextForB</B>
    <C_D>TextForD1</C_D>
    <C_E>TextForE1</C_E>
    <C_D>TextForD2</C_D>
    <C_E_F>TextForF</C_E_F>
    </DocElement>
     
    David Carlisle, Apr 16, 2005
    #2
    1. Advertising

  3. delgados129

    delgados129 Guest

    David:

    Certainly an algorithm of elegance and succinctness! The quick
    response is much appreciated. I hope I can return the favor at some
    point.

    Mario
     
    delgados129, Apr 16, 2005
    #3
    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. Matt
    Replies:
    3
    Views:
    554
    Tor Iver Wilhelmsen
    Sep 17, 2004
  2. Simon

    xsl to flatten xml nodes

    Simon, Apr 12, 2004, in forum: XML
    Replies:
    3
    Views:
    4,246
    Martin Honnen
    Apr 12, 2004
  3. Francis Avila
    Replies:
    0
    Views:
    497
    Francis Avila
    Nov 2, 2003
  4. Tjerk Wolterink
    Replies:
    2
    Views:
    1,520
    Dimitre Novatchev
    Aug 24, 2006
  5. Replies:
    2
    Views:
    415
    Steve Pope
    Sep 27, 2006
Loading...

Share This Page