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

Re: Generating ID key values

Subject: Re: Generating ID key values
From: "Vasu Chakkera" <vasucv@xxxxxxxxx>
Date: Wed, 10 Dec 2008 17:14:00 +0000
Re:  Generating ID key values
I see some issues in your stylesheet.

First: Your complex use of translate function

>  <xsl:variable name="id"
> select="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />

If i devide this into much simpler expression, I will get :

<xsl:variable name = "tr1" select="translate(.,'
abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-','')"/>

<xsl:variable name = "tr2" select="translate(.,$tr1,'')"/>

<xsl:variable name="id" select="translate(normalize-space($tr2),' ','_')" />



so You see, your first translate is not doing anything interesting. It
is translateing your current text to blank space.
your second translate is again not doing anything. It is translating
space into space in your current. text

Hmm. Nothing so far..

Your Id is translating the space into underscore. Fair enuff.

So really only the variable id seems to be doing something, and it
could be written as

<xsl:variable name="id" select="translate(normalize-space(.),' ','_')" />


NExt :

<xsl:template match="*">
		<xsl:copy>
			<xsl:apply-templates select="@*" />
			<xsl:apply-templates />
		</xsl:copy>
	</xsl:template>
	<xsl:template match="@*">
		<xsl:copy-of select="." />
	</xsl:template>

Can be :

<xsl:template match="node()|@*">
		<xsl:copy>
			<xsl:apply-templates select="node()|@*" />
			
		</xsl:copy>
	</xsl:template>
	
** Just a plain identity template

NExt: Your use of Keys and the for each:

Looking at what you really want, i think you are thinking in the
direction of over engineering ..


I think what you want is below.. try it out and let me know if this is
not what you want.


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" encoding="UTF-8" />
	<xsl:template match="node()|@*">
		<xsl:copy>
			<xsl:apply-templates select="node()|@*"/>
		</xsl:copy>
	</xsl:template>
	<xsl:template match="document/*[not(@id)]">
		<xsl:call-template name="copy-elem-giving-id" />
	</xsl:template>
	<xsl:template name="copy-elem-giving-id">
		<xsl:variable name="id" select="translate(normalize-space(.),' ','_')" />
		<xsl:copy>
			<xsl:attribute name="id">
				<xsl:value-of select="$id" />
				<xsl:variable name = "current-node-name" select="name(.)"/>
				<xsl:variable name = "current-node-val" select="$id"/>
				<xsl:variable name = "prefix"
select="count(preceding-sibling::*[not(@id)][(name() =
$current-node-name ) and  translate(normalize-space(.),' ','_') =
$current-node-val])+1"/>
				<xsl:if test = "string($prefix)">
					<xsl:text>-</xsl:text>
				</xsl:if>
				<xsl:value-of select = "$prefix"/>
			</xsl:attribute>
			<xsl:apply-templates select="@*" />
			<xsl:apply-templates />
		</xsl:copy>
	</xsl:template>
</xsl:stylesheet>


2008/12/10 Trevor Nicholls <trevor@xxxxxxxxxxxxxxxxxx>:> Hi
>
> I have a stylesheet which is supposed to generate id attributes for any
> occurrences of particular elements which do not already have one.
> Unfortunately it has a couple of defects.
>
> I am testing in XMLSpy but the stylesheet has to run with Xalan (because
> it's built into a FrameMaker application). Hence we're restricted to XSL 1
> solutions.
>
> The stylesheet is here:
>  =======================
>  <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
>  <xsl:output method="xml" encoding="UTF-8" />
>
>  <!--
>   - NOTE
>   - This stylesheet generates ID attributes for certain elements that
> should have them - but do not.
>   -->
>
>  <!-- set of existing ID values -->
>  <xsl:key name="id" match="*[@id]" use="@id" />
>
>  <!-- set of potential ID values -->
>  <xsl:key name="noid" match="title[not(@id)]"
> use="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />
>  <xsl:key name="noid" match="question[not(@id)]"
> use="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />
>  <xsl:key name="noid" match="dt[not(@id)]"
> use="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />
>  <xsl:key name="noid" match="target[not(@id)]"
> use="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />
>
>  <!-- Fill in any missing IDs -->
>
>  <xsl:template match="title | question | target | dt">
>  <xsl:choose>
>   <xsl:when test="@id">
>    <xsl:call-template name="copy-elem" />
>   </xsl:when>
>   <xsl:otherwise>
>    <xsl:call-template name="copy-elem-giving-id" />
>   </xsl:otherwise>
>  </xsl:choose>
>  </xsl:template>
>
>  <xsl:template name="copy-elem">
>  <xsl:copy>
>   <xsl:apply-templates select="@*" />
>   <xsl:apply-templates />
>  </xsl:copy>
>  </xsl:template>
>
>  <xsl:template name="copy-elem-giving-id">
>  <xsl:variable name="id"
> select="translate(normalize-space(translate(.,translate(.,'
> abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_.-',''),'
> ')),' ','_')" />
>  <xsl:variable name="thisnode" select="generate-id()" />
>  <xsl:copy>
>   <xsl:attribute name="id">
>    <xsl:value-of select="$id" />
>    <xsl:for-each select="key('noid',$id)">
>     <xsl:if test="(key('id',$id)) or (position()!=1 and
> generate-id(.)=$thisnode)">
>      <xsl:text>-</xsl:text>
>      <xsl:value-of select="position()" />
>     </xsl:if>
>    </xsl:for-each>
>   </xsl:attribute>
>   <xsl:apply-templates select="@*" />
>   <xsl:apply-templates />
>  </xsl:copy>
>  </xsl:template>
>
>  <!-- catchall -->
>  <xsl:template match="*">
>  <xsl:copy>
>   <xsl:apply-templates select="@*" />
>   <xsl:apply-templates />
>  </xsl:copy>
>  </xsl:template>
>
>  <xsl:template match="@*">
>  <xsl:copy-of select="." />
>  </xsl:template>
>
>  </xsl:stylesheet>
>  =======================
>
> Sample XML here:
>  =======================
>  <?xml version="1.0" encoding="UTF-8"?>
>  <document>
>  <title id="Intro">Intro</title>
>  <title>Me</title>
>  <title>Intro</title>
>  <title>3 Point Turns</title>
>  <title>Intro</title>
>  </document>
>  =======================
>
> The output I get:
>  =======================
>  <?xml version="1.0" encoding="UTF-8"?>
>  <document>
>  <title id="Intro">Intro</title>
>  <title id="Me">Me</title>
>  <title id="Intro-1-2">Intro</title>
>  <title id="3_Point_Turns">3 Point Turns</title>
>  <title id="Intro-1-2">Intro</title>
>  </document>
>  =======================
>
> The first problem is that instead of generating ID values of "Intro-1" and
> "Intro-2", both titles are given the illegal duplicate ids "Intro-1-2",
> which rather negates the point of using the keys in the first place. I
> thought the <for-each><if /></for-each> construction would only match once,
> but evidently not.
>
> The second problem is that title beginning with a digit. While I can prefix
> the id with an underscore when I create the attribute, I can't see how to do
> the same modification when I construct the key. And if I don't construct the
> "noid" key with the same prefix then I run the risk of failing to detect a
> duplicate id when I create the attribute.
>
> If you can see what I've done wrong I would be most grateful.
>
> Cheers
> Trevor
>
>



-- 
Vasu Chakkera
Numerical Algorithms Group Ltd.
Oxford
www.vasucv.com

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.