RE: [xsl] The notion of Inheritance?

Subject: RE: [xsl] The notion of Inheritance?
From: William Bagby <williamb@xxxxxxxxx>
Date: Thu, 29 Mar 2001 13:19:46 -0500
Jeni,

I am running Cocoon, and you are exactly right about the <param>.

> I don't know whether you didn't try running the code I posted or if
> you tried running it and came back with something strange.

The latter.  Here's the output:

------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
	
		1
		John
		Smith
		
			brown
			black
			6'1"
		
		Software Developer
<!-- MY FORMATTING ADDED HERE -->
	<person>
		<id>2</id>
		<first-name>Mary</first-name>
		<last-name>Jacobs</last-name>
		<physical>
			<eyes>brown</eyes>
			<hair>black</hair>
			<height>6'1"</height>
		</physical>
		<occupation>Welder</occupation>
	</person>
<!-- FORMATTING ENDS -->	
		3
		Joe
		
			blue
--------------------------------------------

It's *almost* right.  I just need to prevent the non-XML stuff from getting
through.

I also tested this with Saxon.


Thanks again for your help,


William.


-----Original Message-----
From: Jeni Tennison [mailto:mail@xxxxxxxxxxxxxxxx]
Sent: Thursday, March 29, 2001 1:13 PM
To: William Bagby
Cc: XSL Mailing List (E-mail)
Subject: Re: [xsl] The notion of Inheritance?


Hi William,

> Almost. It's not exactly what I want. I should've been a little more
> clear. I would only want to match one id at a time. For example,
> suppose I have a URL:
>
> http://www.mydomain.com/people/people.xml?id=2

OK, so you're using Cocoon and have an 'id' parameter defined in your
XSLT stylesheet:

<!-- defaults to id=2 -->
<xsl:parameter name="id" select="2" />

Then you only apply templates to the person that you want:

<xsl:template match="people">
   <xsl:apply-templates select="person[id = $id]" />
</xsl:template>

With that, all you need to do is change the match pattern of the
template that I gave you last time, so that it matches any person, and
trust the XSLT processor to only *apply* it to the one person that
you're interested in.  The old template should have worked too, as
long as the ids that you used were 2 or 3.  But here's the new match
pattern:

<xsl:template match="person">
   <xsl:apply-templates select="../person[id = 1]" mode="inherit">
      <xsl:with-param name="override" select="." />
   </xsl:apply-templates>
</xsl:template>

The rest of the templates are exactly the same:

<xsl:template match="*[*]" mode="inherit">
   <xsl:param name="override" />
   <xsl:copy>
      <xsl:for-each select="*">
         <xsl:apply-templates select="." mode="inherit">
            <xsl:with-param name="override"
               select="$override/*[name() = name(current())]" />
         </xsl:apply-templates>
      </xsl:for-each>
   </xsl:copy>
</xsl:template>

<xsl:template match="*[not(*)]" mode="inherit">
   <xsl:param name="override" />
   <xsl:copy-of select="$override | current()[not($override)]" />
</xsl:template>

This generally follows the description that you give:

> 1. Make a copy of person[id = 1].
> 2. Traverse the nodes, at each node checking whether
> person[id = 2] is defined.
> 3. If it is, overwrite the copied node.  If not, leave it alone.

except that there is no notion of 'overwriting' elements in XSLT
(though there is with attributes, as Mike pointed out). As you're
dealing with elements, you have to create a new result tree, only
putting the nodes that you want to put into it. So you copy bits from
the person[id = 1] element and bits from the person element that
you're interested in, but never the same bits from both.

I don't know whether you didn't try running the code I posted or if
you tried running it and came back with something strange.  I did test
it with Saxon before I posted, so do say what output you're getting if
it's weird.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread