Re: [xsl] Controlling ancestor reference in the result tree

Subject: Re: [xsl] Controlling ancestor reference in the result tree
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 12 Mar 2001 10:53:41 +0000
Hi Roshan,

> While traversing thru the locations in xml below, I have 2 questions:
> Q 1: How do I get the value of the attr named "name" of the ancestor

There are lots of ancestors - I think you're after the parent?  To get
to the parent element's 'name' attribute, go first to the parent:

  ..

and then to its attribute called 'name:

  ../@name

and that's it.

The name() function that you've been using gets the name of the node,
so if your current node is an office element and you do:

  name(..)

you'll get the name 'customer'.  If you just want to check whether
the parent is a customer element, then do:

  parent::customer

that will return boolean true if the parent of the context node is a
customer element.

> Q 2: I recursively call apply-templates for every office locations and
>      want to print customer node info only once.
>
>      The attempt to control with var $did_i_print=1 and marking it "0"
>      failed.

Well, given that the offices have templates applied to them in order,
you could check whether the current node (the office element) has any
preceding office elements:

  preceding-sibling::office

If it hasn't, then it's the first office to be processed, and you
could give the customer information.

However, usually what you'd do is have a template that matched the
customer element and gave information about it, before moving on to
giving information about each of the office elements in turn:

<xsl:template match="customer">
   <!-- give the name of the customer -->
   <xsl:value-of select="@name" />
   <!-- give information about revenue and employees -->
   ...
   <!-- give information about their offices -->
   <xsl:apply-templates select="office" />
</xsl:template>

Thus the customer information is always given before the offices, and
only once per customer.

If you only want this information to be given for customers that have
offices, then either only apply templates to those customers:

  <xsl:apply-templates select="customer[office]" />

or use the match pattern in the template so that it only matches
customers that have offices:

<xsl:template match="customer[office]">
   <!-- give the name of the customer -->
   <xsl:value-of select="@name" />
   <!-- give information about revenue and employees -->
   ...
   <!-- give information about their offices -->
   <xsl:apply-templates select="office" />
</xsl:template>

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