[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Addressing siblings


Subject: RE: [xsl] Addressing siblings
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 9 Feb 2005 10:35:17 -0000

Keys are usually recommended for performance, but when you're handling
cross-references they can also make your code simpler and more
understandable. 

<xsl:key name="man-by-name" match="Man" use="@name"/>
<xsl:key name="woman-by-name" match="Woman" use="@name"/>
<xsl:key name="man-by-wifes-name" match="Man" use="@wife"/>

<xsl:template match="Woman">
  <xsl:apply-templates select="key('man-by-wifes-name', @name)"/>

In 2.0 I often write stylesheet functions to encapsulate a relationship:

<xsl:function name="get-husband" as="element(Man)">
  <xsl:param name="wife" as="element(Woman)">
  <xsl:sequence select="key('man-by-wifes-name', $wife/@name)"/>
</xsl:function>

You can then use this in path expressions rather like a virtual axis:

<xsl:template match="Woman">
  <xsl:value-of select="get-husband(.)/get-children(.)/@date-of-birth"/>


Michael Kay
http://www.saxonica.com/
 

> -----Original Message-----
> From: David.McKay@xxxxxxxxxxxxxxxxxxxxxxxxxxx 
> [mailto:David.McKay@xxxxxxxxxxxxxxxxxxxxxxxxxxx] 
> Sent: 09 February 2005 09:28
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Addressing siblings
> 
> --- XSL Processor Details
> 
> Vendor: SAXON 6.5.3 from Michael Kay
> Vendor URL: http://saxon.sf.net/
> 
> ---
> 
> Say I have some (grossly simplified, politically incorrect, 
> and exclusive of alternate lifestyles) XML which looks 
> something like this:
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <People>
>    <Man name="Bob" wife="Alice" birth="1960-08-15"/>
>    <Woman name="Alice" birth="1955-10-26"/>
> </People>
> 
> 
> To cut a long story short, I have an xsl template which 
> scopes Woman, and I want to set a variable to be that Woman's 
> husband (ie the Man for whom the Woman is the wife). I've 
> come up with the following method:
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
>    <xsl:output method="text" indent="no" encoding="UTF-8"/>
> 
>    <xsl:template match="/">
>       <xsl:apply-templates/>
>    </xsl:template>
> 
>    <!-- various processing -->
> 
>    <xsl:template match="Man" mode="husband">
>       <xsl:value-of select="@name"/>
>    </xsl:template>
> 
>    <xsl:template match="Woman" mode=>
>       <xsl:variable name="me" select="@name"/>
>       <xsl:variable name="husband">
>          <xsl:apply-templates mode="husband" 
> select="../*[@wife=$me]"/>
>       </xsl:variable>
> 
>       <!-- do something with $husband -->
>    </xsl:template>
> </xsl:stylesheet>
> 
> 
> Is there a more compact way (especially since I would want to 
> access the birth attribute too)? I thought something along 
> the lines of the following might work, but I couldn't figure out how.
> 
> 
> <xsl:variable name="husband-birthday" 
> select="../*[@wife=./@name]/@birth"/>
> 
> 
> Thanks.
> 
> Dave McKay
> 
> 
> 
> **********************************************************************
> IMPORTANT NOTICE
> 
> The information contained in this e-mail is confidential. It may also 
> be legally privileged. It is intended only for the stated 
> addressee(s) 
> and access to it by any other person is unauthorised. If you are not 
> an addressee, you must not disclose, copy, circulate or in any other 
> way use or rely on the information contained in this e-mail. Such 
> unauthorised use may be unlawful.
> 
> If you have received this e-mail in error, please inform 
> Racal Instruments Group Ltd. immediately by 
>     emailing  postmaster@xxxxxxxxxxxxxxxxxxxxxxxxxxx 
> or 
>     phoning +44 (0)1202 872800  (ask for the I.T. Dept.) 
> and delete it and all copies from your system.
> 
> www.racalinstrumentsgroup.co.uk
> 
> **********************************************************************


Current Thread
Keywords