xsl-list
[Top] [All Lists]

Re: [xsl] Building a tree from path-like strings

2009-01-03 18:05:26
Happy New Year and Best Wishes to Everyone !

On Sat, Jan 3, 2009 at 10:38 AM, Richard Lewis 
<richard(_dot_)lewis(_at_)gold(_dot_)ac(_dot_)uk> wrote:
Hi there,

I'm trying to make a tree-hierarchic document from a flat
list of elements which have id-like values which define
the hierarchy I need.

In addition to G. Ken Holman's XSLT 1.0 solution, here is an XSLT 2.0 one.

The transformation below produces an XML document from the id-strings:

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
        xmlns:xs="http://www.w3.org/2001/XMLSchema";
        xmlns:my="my:fn"
        exclude-result-prefixes="my xs"
        >
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
        
        <xsl:template match="/*/*">
          <FOO>
            <xsl:sequence select=
             "my:makeTree(*/field[(_at_)name='external_id']/value, 'FOO/')"/>
          </FOO>
        </xsl:template>

        <xsl:function name="my:makeTree">
          <xsl:param name="pIdNodes" as="element()*"/>
          <xsl:param name="pPrefix" as="xs:string"/>
        
          <xsl:for-each-group
              select="$pIdNodes[starts-with(.,$pPrefix)]" group-by=
             "substring-before(concat(substring-after(.,$pPrefix),
                                                        '/'),
                                                       '/')">
                    <xsl:variable name="vElName" select=
                     "concat('V-',current-grouping-key())"/>

                    <xsl:variable name="vNewPrefix" select=
                     "concat($pPrefix, current-grouping-key(),'/')"/>
                
                    <xsl:element name="{$vElName}">
                      <xsl:sequence select=
                       "my:makeTree($pIdNodes, $vNewPrefix)"/>
                    </xsl:element>
                         </xsl:for-each-group>
        </xsl:function>
</xsl:stylesheet>


When the above is applied on the originally provided XML document:

<btc>
        <record table="works">
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/1</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/1/1</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/1/2</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/2</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/2/1</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/2/1/1</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/2/1/2</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/2/2</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
                <record table="external_records">
                        <field name="external_id">
                                <value>FOO/3</value>
                        </field>
                        <field name="ds_name">
                                <value>ms-sources</value>
                        </field>
                </record>
        </record>
</btc>

the result is:

<FOO>
   <V-1>
      <V-1/>
      <V-2/>
   </V-1>
   <V-2>
      <V-1>
         <V-1/>
         <V-2/>
      </V-1>
      <V-2/>
   </V-2>
   <V-3/>
</FOO>

From this tree it is trivial to produce the the desired output and any
other possibly desired output.


-- 
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
Never fight an inanimate object
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>