[xsl] How to "flatten" a XML file with n-ary Cartesian product over n sequences X1, ..., Xn using XSL

Subject: [xsl] How to "flatten" a XML file with n-ary Cartesian product over n sequences X1, ..., Xn using XSL
From: reynaldo.rizzo@xxxxxxxxxxxxxxxx
Date: Fri, 28 Aug 2009 15:21:05 -0200
Hi all,

I'm in need to "flatten" out hierarchical XML input to text files, given 
input similar to the following:

'input.xml'
<root>
    <item>
        <code>01</code>
        <name>name0</name>
        <aList>
            <a>
                <code>10</code>
                <description>description0</description>
            </a>
        </aList>
        <bList>
            <b>
                <code>100</code>
                <description>description2</description>
            </b>
            <b>
                <code>200</code>
                <description>description3</description>
            </b>
        </bList>
        <cList>
            <c>
                <code>996</code>
                <description>description4</description>
            </c>
            <c>
                <code>997</code>
                <description>description5</description>
            </c>
        </cList>
    </item>
    <item>
        <code>02</code>
        <name>name1</name>
        <aList>
            <a>
                <code>20</code>
                <description>description6</description>
            </a>
        </aList>
        <cList>
            <c>
                <code>998</code>
                <description>description10</description>
            </c>
            <c>
                <code>999</code>
                <description>description11</description>
            </c>
        </cList>
    </item>
</root>

The desired output is a delimited file shown as follows:

'output.csv'
root,itemCode,itemName,aCode,aDescription,bCode,bDescription,cCode,cDescription
01,name0,10,description0,100,description2,996,description4
01,name0,10,description0,100,description2,997,description5
01,name0,10,description0,200,description3,996,description4
01,name0,10,description0,200,description3,997,description5
02,name1,20,description6,null,null,998,description10
02,name1,20,description6,null,null,999,description11

Output is the Cartesian product of each item with its own sub-sequences.

I've had limited success with my own limited self-learned XSL skills 
dealing on a per case basis, but I'm not satisfied with the efficiency 
achieved. Because I have no "normalized" approach, complexity of my XSL 
grows considerably, related to the number of sequences involved and I'm 
getting stuck when it involves more than three.

I was wondering if there is any "standard" method that solves this problem 
for n-sequences (i.e. using a <xsl:for-each-group> that groups by item and 
repeat the contents for each sublist?) so I could use recursion or 
iterations according to n. Please note that sequences are optional; the 
schema allows for empty or nonexistent sequences, where in such cases 
'null' must be output for the missing fields.

I'm using Oxygen XML editor with XSL 2.0 running Saxon-B 9.1.0.7. An 
alternative solution using XSL 1.0 will also be most appreciated. 

Thanks for your help!

Reynaldo J. A. Rizzo

Current Thread