Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


Re: [xsl] Benefits of using xsl:key

From: =?iso-8859-1?Q?Michael_M=FCller-Hillebrand?= <mmh@----------.-->
To: xsl-list@-----.------------.---
Date: 11/3/2009 9:22:00 AM
Hi Jesper,

Am 03.11.2009 um 08:55 schrieb Jesper Tverskov:

> We often hear that the use of xsl:key can speed up a transformation
> many times. But XSLT processors seem so optimized for speed, anyway,
> these days, that I have found it difficult to construct a test input
> file and a test XSLT stylesheet demonstrating the dramatic wonders of
> using xsl:key.
>
> How big should the input document be?
> How complicated the hierarchy, etc?
>
> I would like to impress my students with a nice little transformation
> example, instead of just telling them that there can be huge benefits.

about a year ago I had such a situation. With test documents all went  
fine, but the customer used XML files of about 20 MBytes and they  
waited. They complained about it only after months and I was really  
ashamed.

The task was to remove duplicate content from an XML file, to ease the  
translation process. All duplicate elements should be left in the  
result file, but empty and with an extra attribute @xrefid which would  
allow to revert the process after translation.

The input was essentially a list, the original with a lot more  
attributes and of course thousands of entries:

<?xml version="1.0" encoding="UTF-8"?>
<Doc>
  <value oid="f37">some text</value>
  <value oid="f61">some text</value>
  <value oid="f042">some other text</value>
</Doc>

The desired result was:

<?xml version="1.0" encoding="UTF-8"?>
<Doc>
  <value oid="f37">some text</value>
  <value oid="f61" xrefid="f37" />
  <value oid="f042">some other text</value>
</Doc>

My first take was (I know I should have known better):

<xsl:template match="value[.=preceding::value]">
  <xsl:copy>
   <!-- add attribute and skip content -->
   <xsl:apply-templates select="@*"/>
   <xsl:attribute name="xrefid" select="preceding::value[.=current()] 
[last()]/@oid"/>
  </xsl:copy>
</xsl:template>

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


This was really bad with large files, because for every value a look- 
up of all preceding values had to be made. So I changed it to

<xsl:key name="value-content" match="value" use="."/>

<xsl:template match="value">
  <xsl:variable name="first" select="key('value-content', .)[1]"/>
  <xsl:copy>
   <xsl:choose>
    <xsl:when test=". is $first">
     <!-- pass through content -->
     <xsl:apply-templates select="@*"/>
     <xsl:apply-templates/>
    </xsl:when>
    <xsl:otherwise>
      <!-- add attribute and skip content -->
      <xsl:attribute name="xrefid" select="$first/@oid"/>
      <xsl:apply-templates select="@*"/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:copy>
</xsl:template>

Now the solution worked like a breeze with really large files.

HTH,

- Michael

PS: Examples have been edited and not tested.

--
_______________________________________________________________
Michael Müller-Hillebrand: Dokumentations-Technologie
Adobe Certified Expert, FrameMaker
Lösungen und Training, FrameScript, XML/XSL, Unicode
Blog: http://cap-studio.de/ - Tel. +49 (9131) 28747






--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe@l...>
--~--



transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent