xsl-list
[Top] [All Lists]

RE: key(), generate-id question

2002-11-12 05:30:55
Hi Endre.
With this case we have to change a little the templates.
First, the variable lastid have to be global, so we put it as child of
xsl:stylesheet
Then, we'll have to change the two following templates:

 <xsl:template name="generate-id">
  <xsl:variable name="last"
select="number(substring-after($lastid,'id'))"/>
  <xsl:variable name="this" select="count(preceding::*[not(@_id)])+1"/>
<!-- instead of proceding-sibling axis will use the proceding one. This
axis gets all preceding nodes no matter the level they are -->
  <xsl:variable name="temp" select="concat('00000',$last+$this)"/>
  <xsl:value-of
select="concat('id',substring($temp,string-length($temp)-5))"/>
 </xsl:template>

 <xsl:template name="biggest">
  <xsl:for-each select="//*[(_at_)_id]"> <!-- now will have to look in all
elements not just the ones at the same level -->
   <xsl:sort select="number(substring-after(@_id,'id'))"
data-type="number"/>
   <xsl:if test="position()=last()">
   <xsl:value-of select="@_id"/>
   </xsl:if>
  </xsl:for-each>
 </xsl:template>

To wrap it up, here the complete stylesheet:
<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output method="xml" indent="yes"/>

 <xsl:variable name="lastid">
 <xsl:call-template name="biggest"/>
 </xsl:variable>

 <xsl:template match="*">
  <xsl:copy>
  <xsl:copy-of select="@*"/>
  <xsl:attribute name="xmi.id">
  <xsl:choose>
   <xsl:when test="@_id">
   <xsl:value-of select="@_id"/>
   </xsl:when>
   <xsl:otherwise>
   <xsl:call-template name="generate-id"/>
   </xsl:otherwise>
  </xsl:choose>
  </xsl:attribute>
  <xsl:apply-templates/>
  </xsl:copy>
 </xsl:template>

 <xsl:template name="generate-id">
  <xsl:variable name="last"
select="number(substring-after($lastid,'id'))"/>
  <xsl:variable name="this" select="count(preceding::*[not(@_id)])+1"/>
  <xsl:variable name="temp" select="concat('00000',$last+$this)"/>
  <xsl:value-of
select="concat('id',substring($temp,string-length($temp)-5))"/>
 </xsl:template>

 <xsl:template name="biggest">
  <xsl:for-each select="//*[(_at_)_id]">
   <xsl:sort select="number(substring-after(@_id,'id'))"
data-type="number"/>
   <xsl:if test="position()=last()">
   <xsl:value-of select="@_id"/>
   </xsl:if>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of 
Endre,
MAGYARI
Sent: Monday, November 11, 2002 7:57 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: RE: [xsl] key(), generate-id question



Hi,

If the structure of your xml is diferent (probably is) then you can
change the 'element' in the templates by 'node()'

The structure of my XML is stg like that:
<Diagram>                               <-- only one or zero -->
        <Composition>                   <-- 0..* -->
                <CompositionChildRole>  <-- 1-->
                <CompositionParentRole> <-- 1-->
        </Composition>
        <Association>                   <-- 0..* -->
                <AssociationRole>       <-- 2 -->
        </Association>

        <Class>                         <-- 0..* -->
                <Attribute>             <-- 0..* -->

        </Class>
<Diagram>


All of these elements may have _id attribute.

My input XML, for example has no _id attribute for the root element
<Diagram> and for this reason the XSLT code you provided fails at when
tries to evaluate the previous sibling node. There is no such thing.

Because you can not assume any order regarding the input XML, I thought
somehow I need to process first all the nodes in order to obtain the
maximum ID currently present in the Document.

Does this seem reasonable?
Thank you,
Endre

Hope that this helps you.


-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of 
Endre
Magyari
Sent: Monday, November 11, 2002 7:30 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] key(), generate-id question


You can't control how generate-id() works, but you could do
something like write a named template that will generate the ID. For

example, you could count the number of preceding elements that don't

have an _ID attribute and then add that value to the numeric part of

the nearest preceding element that *does* have an _ID attribute. All

doable with normal XSLT functions.


Based on this, as far as now I could do an enumeration of all the _id
values (as numbers) from the document, but I have no idea how to
select the one with the maximal value out of them. And Also, I have no

idea how/where to store the new id values being assigned. The problem
is that I've no experience with declarative languages. I can not get
used to the idea that a variable can not vary. What I would do is that

(if curr_value > max) max = curr_value. But how to do this here? Any
help is greatly appreciated.

<!-- ID Generator-->
<xsl:template name="idgen">
    <xsl:for-each select="node()">
        <xsl:for-each select="@_id">
            <xsl:number value="substring-after(current(),'id')"/>;
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

Thank you,
Endre


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


--

ing. dipl. ENDRE Magyari                                
endre(_at_)nextra(_dot_)ro
software engineer
office:+40-66-171200
system administrator
mobile:+40-94-794735
Nextra Ltd.                Florilor no 28/1. RO-4100 Miercurea Ciuc.
ROMANIA


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>