The CD Man
The CD Man

Reputation: 45

Combining nodes from different files to make one file using XSLT

I have several files with data and I want to group some nodes and make one file. I have given only 2 sample files but it can be many. The input files are listed in an xml file as includes (list.xml).

Basically, the grouping should be done according to the of each file and each should be listed as node for that particular functional area.

Is this possible to do with XSLT? Maybe with more than one transformation?

File list : list.xml

<?xml version="1.0" encoding="UTF-8"?>
<index xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="xml/models/1c8dca64-8b40-4e58-8581-5104f5ca3f3e.xml"/>
   <xi:include href="xml/models/7f10e39d-ca8c-4c17-9a0f-2dcbceaaed51.xml"/>
   <xi:include href="xml/models/2d90b9b4-793c-4d8b-9e06-0a93dfa738a2.xml"/>
   <xi:include href="xml/models/4ee7085e-8241-4dae-a095-38ede5fd7fb0.xml"/>
</index>

Input File 01 : 1c8dca64-8b40-4e58-8581-5104f5ca3f3e.xml

<model>
   <contains>
      <vertex>
         <functionalarea>Supply Chain</functionalarea>
         <breakdowns>
            <model>34c1e701-5a70-4493-b877-38624348947c</model>
         </breakdowns>
      </vertex>
      <vertex>
         <functionalarea>Supply Chain</functionalarea>
         <breakdowns>
            <model>25a39e71-aa59-4f63-9c09-8cc4e36bae72</model>
         </breakdowns>
      </vertex>
      <vertex>
         <functionalarea>Planning</functionalarea>
         <breakdowns>
            <model>45c0d6c3-a910-4050-b10e-f17eb7276c44</model>
         </breakdowns>
      </vertex>
   </contains>
</model>

Input File 02 : 7f10e39d-ca8c-4c17-9a0f-2dcbceaaed51.xml

<model>
   <contains>
      <vertex>
         <functionalarea>Supply Chain</functionalarea>
         <breakdowns>
            <model>58a77718-1e95-408b-a6ae-f185348ec310</model>
         </breakdowns>
      </vertex>
      <vertex>
         <functionalarea>Planning</functionalarea>
         <breakdowns>
            <model>87767baa-bab9-46dd-80d8-a0d0c3993429</model>
         </breakdowns>
      </vertex>
      <vertex>
         <functionalarea>Execution</functionalarea>
         <breakdowns>
            <model>f21aef69-9772-49bd-b6c1-4f3e55fc3887</model>
         </breakdowns>
      </vertex>
   </contains>
</model>

Required output

<tree>
    <node>
       <name>Supply Chain</name>
       <children>
          <child>34c1e701-5a70-4493-b877-38624348947c</child>
          <child>25a39e71-aa59-4f63-9c09-8cc4e36bae72</child>
          <child>58a77718-1e95-408b-a6ae-f185348ec310</child>
       </children>
    </node>
    <node>
       <name>Planning</name>
       <children>
          <child>45c0d6c3-a910-4050-b10e-f17eb7276c44</child>
          <child>87767baa-bab9-46dd-80d8-a0d0c3993429</child>
       </children>
    </node>
    <node>
       <name>Execution</name>
       <children>
          <child>f21aef69-9772-49bd-b6c1-4f3e55fc3887</child>
       </children>
    </node>
</tree>

Upvotes: 0

Views: 249

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

First bind a variable $models to the set of model elements, which you can do in a number of ways, for example

<xsl:variable name="models" select="//@href/document(.)/*"/>

Then do the grouping:

<xsl:for-each-group select="$models/*/vertex" group-by="functionalarea">
    <node>
       <name><xsl:value-of select="current-grouping-key()"/></name>
       <children>
          <xsl:for-each select="current-group()">
            <child><xsl:value-of select=".//model"/></child>
          </xsl:for-each>
       </children>
    </node>
</xsl:for-each-group>

Upvotes: 1

Related Questions