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

generate-id for identical elements

Subject: generate-id for identical elements
From: JBryant@xxxxxxxxx
Date: Thu, 23 Sep 2004 12:13:37 -0500
generate id
Hi,

I apologize for the length of the message. I have included XML, XSL, and 
HTML snippets, so it's rather long. I also apologize for posting from 
Lotus Notes, but I don't have and can't get a different e-mail program 
here at my client site (the IT department frowns on anything but Notes). I 
hope using Notes won't cause too much trouble.

To summarize the problem, I have identical elements (but they do have 
different parent elements), and I am trying to get cross-references to 
these identical elements with generate-id(). I've solved the problem 
without generate-id() by concatenating a unique identifier from the titles 
of the elements (child and parent). I've also solved the problem of 
cross-references with a key and generate-id() - that's the solution I use 
for production documents at present. However, that system does not allow 
two elements to have identical titles. I would like to remove that 
limitation and still use generate-id() - rather than having to key in a 
long identifier for each cross-reference.

The following XML structure represents the problem:

<book>
  <chapter title="Chapter 1">
    <paragraph>The remainder of this book contains the following 
material:</paragraph>
    <list type="bulleted">
      <listitem><ref target="chapter|Chapter 2">Chapter 2</ref>
        <list type="bulleted">
          <listitem><ref target="chapter|Chapter 
2/topic|Introduction">Introduction</ref></listitem>
        </list>
      </listitem>
      <listitem><ref target="chapter|Chapter 3">Chapter 3</ref>
        <list type="bulleted">
          <listitem><ref target="chapter|Chapter 
3/topic|Introduction">Introduction</ref></listitem>
        </list>
      </listitem>
    </list>
  </chapter>
  <chapter title="Chapter 2">
    <topic title="Introduction"/>
  </chapter>
  <chapter title="Chapter 3">
    <topic title="Introduction"/>
  </chapter>
</book>

As you can see, some elements (<topic title="Introduction"/>) are 
identical. However, they are the children of non-identical elements 
(<chapter title="Chapter 2"/> and <chapter title="Chapter 2/">).

I've tried all kinds of things, but I can't get generate-id() to give me 
the same path that it assigns to the referenced element. Just so you'll 
have something to work with and get an idea of my thinking (wrong as it 
is), here's the current stylesheet (representing the last of MANY failed 
ideas) :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="chapter">
    <h1><a name="{generate-id()}"/><xsl:value-of select="@title"/></h1>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="list">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <xsl:template match="listitem">
    <li><xsl:apply-templates/></li>
  </xsl:template>

  <xsl:template match="paragraph">
    <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="ref">
    <xsl:variable name="reftext">
      <xsl:call-template name="makeRef">
        <xsl:with-param name="inString" select="@target"/>
      </xsl:call-template>
    </xsl:variable>
    <a href="#{generate-id(//$reftext)}"><xsl:value-of select="."/></a>
  </xsl:template>

  <xsl:template match="topic">
    <h3><a name="{generate-id()}"><xsl:value-of select="@title"/></a></h3>
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template name="makeRef">
    <xsl:param name="inString"/>
    <xsl:choose>
      <xsl:when test="contains($inString, '/')">
        <xsl:variable name="thisPart" select="substring-before($inString, 
'/')"/>
        <xsl:value-of 
select="substring-before($thisPart,'|')"/>[@title='<xsl:value-of 
select="substring-after($thisPart, '|')"/>']/
        <xsl:call-template name="makeRef">
          <xsl:with-param name="inString" 
select="substring-after($inString, '/')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of 
select="substring-before($inString,'|')"/>[@title='<xsl:value-of 
select="substring-after($inString, '|')"/>']
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Here's the output from Saxon 8 (with a little hand formatting for clarity 
and brevity):

<html>
  <body>
    <h1><a name="d1e3"></a>Chapter 1</h1>
      <p>The remainder of this book contains the following material:</p>
      <ul>
        <li><a href="#d2">Chapter 2</a>
          <ul>
            <li><a href="#d3">Introduction</a></li>
          </ul>
        </li>
        <li><a href="#d4">Chapter 3</a>
          <ul>
            <li><a href="#d5">Introduction</a></li>
          </ul>
        </li>
      </ul>
    <h1><a name="d1e36"></a>Chapter 2</h1>
    <h3><a name="d1e38">Introduction</a></h3>
    <h1><a name="d1e41"></a>Chapter 3</h1>
    <h3><a name="d1e43">Introduction</a></h3>
  </body>
</html>

I gather that generate-id is treating the path I build as a string, so 
it's not working.

My concern is not how to get generate-id to accept a string as a path 
(though I would be curious about that). My concern is to be able to create 
cross-references to identical elements (that do have different parent 
elements). I have total control over the XML input and the XSL stylesheet, 
so I am open to ANY idea that will get the job done.

Thanks very much.

Jay Bryant
Bryant Communication Services

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

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