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

RE: Conditioned merge of XML from two files

Subject: RE: Conditioned merge of XML from two files
From: cknell@xxxxxxxxxx
Date: Wed, 27 Jul 2005 17:13:38 -0400
download alice in wonderland 1999
Karl, the next time you think you need an <xsl:for-each>, stop. Stand up, walk around a little bit, maybe take a cold shower, and think again. Almost the only time you need one is if you are sorting or grouping. It is procedural programmer's security blanket. Let it go.

Now, assuming that each <loc_id> in the locations XML file is unique, this stylesheet will do what you asked. I couldn't figure out what the template matching the <event> element was supposed to do, so I took the liberty of assuming that you meant that to be a <book> element and proceeded accordingly. I named the locations file "kkoch5.xml" on my file system. This stylesheet should do the trick. 

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" encoding="UTF-8" />
 <xsl:strip-space elements="*" />
 <xsl:variable name="locs" select="document('kkoch5.xml')" />

 <xsl:template match="/">
  <xsl:apply-templates />
 </xsl:template>

 <xsl:template match="bookshelf">
  <xsl:apply-templates />
 </xsl:template>

 <xsl:template match="book">
  <xsl:copy>
   <xsl:apply-templates />
  </xsl:copy>
 </xsl:template>

 <xsl:template match="location">
  <xsl:copy>
   <xsl:apply-templates />
   <xsl:copy-of select="$locs/locations/location[loc_id = loc_id]/*[local-name() != 'loc_id']" />
  </xsl:copy>
 </xsl:template>

 <xsl:template match="id|title|desc|loc_id">
  <xsl:copy-of select="." />
 </xsl:template>


</xsl:stylesheet>
-- 
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Karl Koch <TheRanger@xxxxxxx>
Sent:     Wed, 27 Jul 2005 22:43:42 +0200 (MEST)
To:       "Mulberry list" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:   Conditioned merge of XML from two files

Hello Experts,

I have a question resulting from a problem I could not resolve. I have one
XML file which contains information about books (books.xml). I have a second
xml file which contains information about book locations (locations.xml). I
have a location id in books.xml and each location in locations.xml has a
location id of the same sort. I would like to have a stylesheet that looks
up the ids from books.xml in locations.xml and copies the location into a
certain position of the book. After the transformation, each book in
books.xml has a location XML stubstructure.

Here example data from both XML files:

(books.xml - only one book to keep it short)

<bookshelf>
  <book>
    <id>1</id>
    <title>Alice in Wonderland</title>
    <desc>Alice is tumbling down the rabit hole.</desc>
    <location>
      <loc_id>L2</loc_id>
    </location>
  </book>
  ... and many many more ...
</bookshelf>


(locations.xml - only one location to keep it short)

<locations>
  <location>
    <loc_id>L1</loc_id>
    <name>Location 1</name>
    ... many more attributes...
  </location>
  .. many more locations
</locations>


After the transformation I wouild like to have the following:

<bookshelf>
  <book>
    <id>1</id>
    <title>Alice in Wonderland</title>
    <desc>Alice is tumbling down the rabit hole.</desc>
    <location>
      <loc_id>L1</loc_id>
      <name>Location 1</name>
      ... many more attributes...
    </location>
  </book>
  ... and many many more ...
</bookshelf>


I have developed the following XSLT:


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" encoding="UTF-8" />
  <xsl:strip-space elements="*" />
  <xsl:variable name="locationFile" select="document('locations.xml')" />
  
  <!-- Match with root -->
  <xsl:template match="/">
    <bookshelf>
    	<xsl:for-each select="/bookshelf/book">
     		<book>
	        		<xsl:apply-templates select="." />
	        </book>
      	</xsl:for-each>
    </bookshelf>    
   </xsl:template>

  <xsl:template match="event">
    	<xsl:copy-of select="./id" />
    	<xsl:copy-of select="./title" />
    	<xsl:copy-of select="./desc" />
    	<location>
    		<xsl:copy-of
select="$locationFile/locations/location/*[.//location/loc_id=$locationFile/locations//location/id]"/>
    	</location>
   </xsl:template>
       	
</xsl:stylesheet>



.. however, it does not work: What is wrong? I guess it is far from optimal
anyway so I am happy to get completely different solutions as well. As you
can see in the stylesheet, I would like to "hardcode" the lcoations file,
but provide the book data as parameter (for flexiblity reasons).

Any form of help would be highly appreciated.

Kind regards,
Karl





-- 
5 GB Mailbox, 50 FreeSMS http://www.gmx.net/de/go/promail
+++ GMX - die erste Adresse f|r Mail, Message, More +++

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.