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


Subject: Re:
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 10 Jan 2002 10:11:35 +0000
copy of starts with
Hi Smita,

> I want to read file1.xml and update the field attributes in
> file2.xml to contain the name attribute and write the whole thing to
> file3.xml

OK. First you should set up variables holding the root nodes of the
two trees, so that you can easily switch between trees:

<xsl:variable name="file1" select="document('file1.xml')" />
<xsl:variable name="file2" select="/" />

[Assuming file2.xml is the source of the transformation, so you don't
need to access its root node via the document() function explicitly.]

The main thing that you want to do with file2.xml is just copy
everything that's there (it's only the fieldN elements that need to be
changed). You can do this with an identity template, such as:

<xsl:template match="@*|node()">
    <xsl:apply-templates select="@*|node()" />

Then you need to have a special template that deals with the fieldN
elements. Since they all have different names, you need a funny match
that actually tests the string value of the name of the element to see
what it starts with 'field' (it would be better XML design, in my
opinion, and easier to process with XSLT, if you had field elements
with a 'num' attribute holding the number of the field):

<xsl:template match="*[starts-with(name(), 'field')]">

Mostly you want to copy the fieldN element that you're on, along with
its existing attributes:

<xsl:template match="*[starts-with(name(), 'field')]">
    <xsl:copy-of select="@*" />

But you also want to retrieve the name attribute of the same-named
fieldN element in file2.xml. The way I'd do this would be to create a
key that indexes the fieldN elements by their name, as follows:

<xsl:key name="fields" match="*[starts-with(name(), 'field')]"
         use="name()" />

You can then get the field in the current document called 'field2'

  key('fields', 'field2')

and (given that's file1.xml) copy the name attribute of that field

  <xsl:copy-of select="key('fields', 'field2')/@name" />

However, because keys only work in the same document as the current
node, you need to change the context to file1.xml to make sure that it
looks in that document. You can do this with xsl:for-each:

  <xsl:for-each select="$file1">
    <xsl:copy-of select="key('fields', 'field2')/@name" />

The 'field2' needs to be replaced by the name of the fieldN element
that you're currently processing. Since the current node changes (by
going within the xsl:for-each, you need to put that in a variable
outside the xsl:for-each, as follows:

  <xsl:variable name="field" select="name()" />
  <xsl:for-each select="$file1">
    <xsl:copy-of select="key('fields', $field)/@name" />

Putting that in the template, you get:

<xsl:template match="*[starts-with(name(), 'field')]">
    <xsl:copy-of select="@*" />
    <xsl:variable name="field" select="name()" />
    <xsl:for-each select="$file1">
      <xsl:copy-of select="key('fields', $field)/@name" />

I hope that helps,


Jeni Tennison

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

Current Thread


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.
First Name
Last Name
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.