XSL to flatten selective node in XML Doc

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • delgados129

    XSL to flatten selective node in XML Doc

    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="attribFor A">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="attribFor A">TextForA</A>
    <B>TextForB</B>
    <C_D>TextForD 1</C_D>
    <C_E>TextForE 1</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

  • David Carlisle

    #2
    Re: XSL to flatten selective node in XML Doc


    something like this:

    flat.xml
    ========

    <DocElement>
    <A attr="attribFor A">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:styleshe et
    version="1.0"
    xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"[color=blue]
    >[/color]

    <xsl:strip-space elements="*"/>
    <xsl:output 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}_{nam e()}">
    <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="attribFor A">TextForA</A>
    <B>TextForB</B>
    <C_D>TextForD 1</C_D>
    <C_E>TextForE 1</C_E>
    <C_D>TextForD 2</C_D>
    <C_E_F>TextForF </C_E_F>
    </DocElement>

    Comment

    • delgados129

      #3
      Re: XSL to flatten selective node in XML Doc

      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

      Comment

      Working...