W3C home > Mailing lists > Public > www-xsl-fo@w3.org > June 2003

Re: FW: Outputting element name and position as element ID

From: G. Ken Holman <gkholman@CraneSoftwrights.com>
Date: Thu, 12 Jun 2003 09:52:18 -0400
Message-Id: <5.2.0.9.0.20030612093836.00bc3540@pop.storm.ca>
To: <www-xsl-fo@w3.org>

At 2003-06-12 08:44 -0400, Teresa Rippeon wrote:
>I am transforming XML data to XML data and want to insert an ID for each 
>child element of a particular parent:

This is more of an XSLT issue than an XSL-FO issue, and you've posted your 
question to a list focusing on XSL-FO ... XSLT and XPath questions would be 
better posted to the following list:

   http://www.mulberrytech.com/xsl/xsl-list

There are a number of subscribers who would enthusiastically respond to 
such questions.

There is also an *excellent* FAQ at:

   http://www.dpawson.co.uk

>For example, I have the following XML data:
>...
>I would like to add in an ID for each Para and List element of the 
>BlockContent element, based on the Block elements ID. The requested result 
>is as follows:

Is it necessary for you to preserve the ID values or only preserve their 
uniqueness?  If you are merely going to an XSL-FO instance then you 
probably do not need to preserve the values as they are and you will only 
need to preserve uniqueness and you can obtain uniqueness on all nodes of 
an instance by using the generate-id() function which is provided in XSLT 
expressly for this purpose.

But, I note that your example is building nested value ID strings upon 
ancestral values ... IDs are typically totally opaque and used without any 
pattern or visibility.  I'm not sure why it is important to you to 
systematically build new ID values ... this isn't necessary if your only 
objective is to make them unique since the generate-id() is available to you.

However ... continuing with your approach:

><Block ID="B_35000">
>...
>         <Para ID="B_35000_1">This is the RLO introduction</Para>
>...
>         <List ID="B_35000_2">
>...
>         <Para ID="B_35000_3">This is the paragraph after the list</Para>
>...
>I am currently using the following XSL code, which obviously goes through 
>the Para elements first, then the List elements second, so it destroys the 
>original order:

Using the "pull" model (xsl:for-each) will do this destruction ... use the 
"push" model (xsl:apply-templates/xsl:template) in order to preserve the 
original order.

>How can I get the element name and write out the element name with the 
>appropriate attribute based on the $BLOCKID and position of the element, 
>and then obviously write out the element content?

In XSLT you cannot "go back" and fill in information afterwards.  You are 
obliged to produce your result tree in result parse order.  You will need 
to build your unique ID values *as you are writing out the content*.

Building string patterns using position() is unsafe because position() is 
based on how the nodes are processed, not on where the nodes are found in 
the source node tree.  It looks to me like you want the position to be a 
reflection of where the construct is found in the source node tree.

If you are unable to use generate-id() and you still feel compelled to 
synthesize your own unique values from the ID string in Block, then for 
each of Para and List you could construct the value using:

   <xsl:attribute name="ID">
     <xsl:value-of select="ancestor::Block[1]/@ID"/>
     <xsl:text>_</xsl:text>
     <xsl:number count="Para|List"/>
   </xsl:attribute>

If your List constructs are nested, the above will not generate unique 
values, and you will need to change it to be:

   <xsl:attribute name="ID">
     <xsl:value-of select="ancestor::Block[1]/@ID"/>
     <xsl:text>_</xsl:text>
     <xsl:number count="Para|List" from="Block" level="any"/>
   </xsl:attribute>

The <xsl:number/> works based on the location of constructs in the source 
node tree regardless of the order or selection of nodes being processed at 
a given point in time ... which impacts on the position() function.

I hope this helps.

.................. Ken


--
Upcoming hands-on courses: (registration still open!)
-      (XSLT/XPath and/or XSL-FO) North America: June 16-20, 2003

G. Ken Holman                mailto:gkholman@CraneSoftwrights.com
Crane Softwrights Ltd.         http://www.CraneSoftwrights.com/f/
Box 266, Kars, Ontario CANADA K0A-2E0   +1(613)489-0999 (F:-0995)
ISBN 0-13-065196-6                      Definitive XSLT and XPath
ISBN 0-13-140374-5                              Definitive XSL-FO
ISBN 1-894049-08-X  Practical Transformation Using XSLT and XPath
ISBN 1-894049-11-X              Practical Formatting Using XSL-FO
Member of the XML Guild of Practitioners:    http://XMLGuild.info
Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
Received on Thursday, 12 June 2003 09:52:45 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 3 October 2007 16:06:11 GMT