xsl-list
[Top] [All Lists]

RE: Conditioned merge of XML from two files

2005-07-27 14:13:38
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(_at_)onebox(_dot_)com - email



-----Original Message-----
From:     Karl Koch <TheRanger(_at_)gmx(_dot_)net>
Sent:     Wed, 27 Jul 2005 22:43:42 +0200 (MEST)
To:       "Mulberry list" <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Subject:  [xsl] 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 +++

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>