[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: combining multiple xml files

Subject: Re: combining multiple xml files
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 20 May 2003 18:10:35 -0400
xslt combining multiple xml files
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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.