xsl-list
[Top] [All Lists]

RE: generate-id() and setting an ID attribute uniquely in t he XML output for the same source node output twice.

2003-11-18 11:06:05
Dave,

One way you can set unique ids with a combination of generate-id(), and
xsl:with-param
(the rough sample XSL took a bit of time to slog through, but I modified
what you had and came up with this variation)

This XSL:

<xsl:template match="/">
 <resultdoc>
  <newstructure_e1>
   <xsl:apply-templates select="doc/textlevel[(_at_)id='textlevel1']">
    <xsl:with-param name="dif" select="concat(generate-id(),'-a')" />
   </xsl:apply-templates>
  </newstructure_e1>
  <newstructure_e2>
   <xsl:apply-templates select="doc/textlevel[(_at_)id='textlevel1']">
    <xsl:with-param name="dif" select="concat(generate-id(),'-b')" />
   </xsl:apply-templates>
  </newstructure_e2>
 </resultdoc>
</xsl:template>

<xsl:template match="doc/textlevel">
 <xsl:param name="dif" />
 <textlevel>
  <xsl:apply-templates >
   <xsl:with-param name="dif" select="concat(generate-id(),$dif)" />
  </xsl:apply-templates>
 </textlevel> 
</xsl:template>

<xsl:template match="//span">
 <xsl:param name="dif" />
 <NEWspan>
  <xsl:attribute name="id">
   <xsl:value-of select="$dif"/>
  </xsl:attribute>
 </NEWspan>
</xsl:template>

<xsl:template match="i">
 <NEWi>
  <xsl:value-of select="."/>
 </NEWi>
</xsl:template>

<xsl:template match="b">
 <NEWb>
  <xsl:value-of select="."/>
 </NEWb>
</xsl:template>

Produces this result (which is what I think you asked for):

<resultdoc>
   <newstructure_e1>
      <textlevel>
         <NEWi>text text text</NEWi>
         <NEWspan id="d0e2d0-a"/> text text 
<NEWb>text</NEWb>
      </textlevel>
   </newstructure_e1>
   <newstructure_e2>
      <textlevel>
         <NEWi>text text text</NEWi>
         <NEWspan id="d0e2d0-b"/> text text 
<NEWb>text</NEWb>
      </textlevel>
   </newstructure_e2>
</resultdoc>



Good luck,

Bryan

-----Original Message-----
From: David Holden [mailto:dh(_at_)iucr(_dot_)org] 
Sent: Tuesday, November 18, 2003 7:56 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] generate-id() and setting an ID attribute uniquely in the XML
output for the same source node output twice.




Hi,

 I have a source document something like this:

<doc>
      <textlevel id="textlevel1">

       <!-- 
     text marked up using xml tags, e.g. i for italic, b for bold, formula
for       
math etc.. one of which is a "span" tag, e.g.
       -->

      <i>text text text</i> <span id="s1">text text text</span> text text 
<b>text</b>

   </textlevel>

  <!-- etc.... -->

</doc>


I need to transform this document and all of its text level markup to XML 
conforming to a different DTD, so I have template rules for all the source 
elements mapping to the target elements.


However I also need to make a structural change such that the textlevel 
element with id="textlevel1" and all of its contents after transformation
are 
output in two different places in the resulting XML.


for example the result document may look like.

<resultdoc>
    <newstructure_e1>
   
        <textlevel>

                   <!-- source elements transformed to new DTD source
element, 
one of which is a span element -->

      <newi>text text text</newi> <newspan id="s1">text text text</newspan> 
text text <newb>text</newb>

        </textlevel>
    </newstructure_e1>
    <newstructure_e2>

        <textlevel>

                   <!-- source elements transformed to new DTD source
element 
one of which is a span element -->

      <newi>text text text</newi> <newspan id="s2">text text text</newspan> 
text text <newb>text</newb>


       </textlevel>
    </newstructure_e2>
</resultdoc>


so the xsl may be 

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

<resultdoc>
   <newstructure_e1>
       <xsl:template apply-templates="/doc/textlevel[(_at_)id="id1"]>
   </newstructure_e1>
   <newstructure_e2>
       <xsl:template apply-templates="/doc/textlevel[(_at_)id="id1"]>
   </newstructure_e2>
</resultdoc>

<xsl:template match="/doc/textlevel">
    <textlevel>
        <xsl:template apply-templates/>
    </textlevel>
</xsl:template>

<xsl:template match="//span">
   <xsl:attribute name="id">
       <xsl:value-of select="./@id"/>
   </xsl:attribute>
</xsl:template>
      
<!-- other element mappings -->




The problem I have is how do I give the second output of the span element a 
unique ID, I don't care what the ID of the span elements are in the output 
document so long as they are unique.

I can't use generate-id() in the //span template since this bases it value
on 
the position in the source document which is the same for both.



I've though about using "modes", e.g., in the first callout

 <xsl:template apply-templates="/doc/textlevel[(_at_)id="id1"]>

and in the second callout

 <xsl:template apply-templates="/doc/textlevel[(_at_)id="id1"]
mode="differentid">

but then I have to provide two templates for all the other textlevel
elements 
one with a mode and one with out (the actual document is more complicated 
than this.)

  Any ideas,

 thanks,

 Dave.


-- 
Dr. David Holden. (Systems Developer)
Crystallography Journals Online: <http://journals.iucr.org>

Thanks in advance:-
Please avoid sending me Word or PowerPoint attachments.
See: <http://www.fsf.org/philosophy/no-word-attachments.html>

UK Privacy (R.I.P)  : http://www.stand.org.uk/commentary.php3
Public GPG key available on request.
-------------------------------------------------------------

 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>