Re: [xsl] combining multiple xml files

Subject: Re: [xsl] combining multiple xml files
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 May 2003 18:10:35 -0400
At 2003-05-20 14:03 -0500, RJ P wrote:
I am wanting to combine multiple xml files looking as follows:
...
and have the output look as such...any suggestions?

The solution is straightforward when using variables and I believe would be easier than trying to use keys (if it were even possible, I haven't tried this using keys).


A working solution is below. Unfortunately, you didn't describe the constraints at all on ids and names, so I made some assumptions.

The crux of the solution is to reduce variables of nodes into other variables that represent nodes that may be duplicated, and then selecting uniquely-valued nodes out of the duplicates and going "one level deeper" to get the next collection. Note my choice of variable names at each depth level. The approach is very symmetrical at each step. I also assumed that you wanted to weed out duplicate detail records, though your data didn't have duplicates.

For your limited data sample, the code below produces your required output ... I'm not sure if it would work for all of your data.

I hope this helps.

.......................... Ken

p.s. seats are still available in our June 16-18 XSLT training, that is followed June 19-20 by our XSL-FO training; we cover variable-based grouping in the XSLT course as one of the three methods of grouping, the other two being axis-based and key-based.

t:\ftemp>type rj1.xml
<class>
              <id>001</id>
              <name>beginning</name>
        <section>
                <id>100</id>
                <name>Anderson</name>
                <detail>some text</detail>
        </section>
</class>

t:\ftemp>type rj2.xml
<class>
        <id>001</id>
        <name>beginning</name>
        <section>
                <id>100</id>
                <name>Anderson</name>
                <detail>some more text</detail>
        </section>
</class>

t:\ftemp>type rj3.xml
<class>
        <id>001</id>
        <name>beginning</name>
        <section>
                <id>200</id>
                <name>Anderson</name>
                <detail>more text</detail>
        </section>
</class>

t:\ftemp>type rj4.xml
<class>
        <id>002</id>
        <name>advanced</name>
        <section>
                <id>100</id>
                <name>Jones</name>
                <detail>some final text</detail>
        </section>
</class>

t:\ftemp>type rj.xsl
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output indent="yes"/>

<xsl:variable name="classes" select="document('rj1.xml')/class |
                                     document('rj2.xml')/class |
                                     document('rj3.xml')/class |
                                     document('rj4.xml')/class"/>

<!--this solution pairs id and name at all times-->

<xsl:template match="/">
  <output>
    <xsl:for-each select="$classes">
      <xsl:if test="generate-id(.)=
                    generate-id($classes[id=current()/id and
                                         name=current()/name])">
        <class>
          <id><xsl:value-of select="id"/></id>
          <name><xsl:value-of select="name"/></name>
          <xsl:variable name="classesbyidandname"
                        select="$classes[id=current()/id and
                                         name=current()/name]"/>
          <xsl:for-each select="$classesbyidandname">
            <xsl:if test="generate-id(.)=
                          generate-id($classesbyidandname
                                      [section/id=current()/section/id and
                                       section/name=current()/section/name])">
              <xsl:variable name="sections"
                            select="$classesbyidandname
                                      [section/id=current()/section/id and
                                       section/name=current()/section/name]
                                    /section"/>
              <xsl:for-each select="$sections">
                <xsl:if test="generate-id(.)=
                              generate-id($sections[id=current()/id and
                                                    name=current()/name])">
                  <section>
                    <id><xsl:value-of select="id"/></id>
                    <name><xsl:value-of select="name"/></name>
                    <xsl:variable name="details"
                                  select="$sections[id=current()/id and
                                                    name=current()/name]
                                          /detail"/>
                    <xsl:for-each select="$details">
                      <xsl:if test="generate-id(.)=
                                    generate-id($details[.=current()])">
                        <detail><xsl:value-of select="."/></detail>
                      </xsl:if>
                    </xsl:for-each>
                  </section>
                </xsl:if>
              </xsl:for-each>
            </xsl:if>
          </xsl:for-each>
        </class>
      </xsl:if>
    </xsl:for-each>
  </output>
</xsl:template>

</xsl:stylesheet>

t:\ftemp>saxon -o rjout.xml rj.xsl rj.xsl

t:\ftemp>type rjout.xml
<?xml version="1.0" encoding="utf-8"?>
<output>
   <class>
      <id>001</id>
      <name>beginning</name>
      <section>
         <id>100</id>
         <name>Anderson</name>
         <detail>some text</detail>
         <detail>some more text</detail>
      </section>
      <section>
         <id>200</id>
         <name>Anderson</name>
         <detail>more text</detail>
      </section>
   </class>
   <class>
      <id>002</id>
      <name>advanced</name>
      <section>
         <id>100</id>
         <name>Jones</name>
         <detail>some final text</detail>
      </section>
   </class>
</output>



--
Upcoming hands-on courses: (registration still open!)
-      (XSLT/XPath and/or XSL-FO) North America: June 16-20, 2003

G. Ken Holman                mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.         http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0   +1(613)489-0999 (F:-0995)
ISBN 0-13-065196-6                      Definitive XSLT and XPath
ISBN 0-13-140374-5                              Definitive XSL-FO
ISBN 1-894049-08-X  Practical Transformation Using XSLT and XPath
ISBN 1-894049-11-X              Practical Formatting Using XSL-FO
Male Breast Cancer Awareness http://www.CraneSoftwrights.com/s/bc


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread