Re: [xsl] double document merge using keys

Subject: Re: [xsl] double document merge using keys
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Thu, 24 Jun 2010 16:14:50 +0100
It would get horribly inefficient if you had millions of pages, but if you only have a hundred or so, you can key the lesson on every page in its range thus:

<xsl:key name="p" match="Chapterlesson" use="startNum to endNum"/>

You can then find the Chapterlessons that have some overlap with a given range using

(for $p in $localStart to $localEnd return key('p', $p)) | ()

(The | () is to eliminate duplicates)

and then you can filter this to find those that are wholly within your range rather than merely having some overlap.

However, on reflection, I think this is unlikely to perform any better than a straight search of the data using a predicate.

If you really need a high-performance solution then some kind of sort-merge-grouping process might be the answer - but it will be complex.

Michael Kay
Saxonica

On 24/06/2010 15:36, Terry Ofner wrote:
Is it possible to "key" on two values during a document merge? Let me explain.

I have document that includes lesson name and the page range of the lesson:

Writing with Power
Pages 512

Collaborating Through the Writing Process
Pages 1332

I have transformed the information into the following xml:

<chapter>
        <Chapterlesson code="6.1.1">
          <ch>1</ch>
          <lesson>Writing with Power</lesson>
          <startNum>5</startNum>
          <endNum>12</endNum>
       </Chapterlesson>
       <Chapterlesson code="6.1.2">
          <ch>1</ch>
          <lesson>Collaborating Through the Writing Process</lesson>
          <startNum>13</startNum>
          <endNum>32</endNum>
       </Chapterlesson>
...
</chapter>

I have a set of standards that need to be aligned with each lesson. The standards are coded to the page, not the lesson. Here is a snippet of the current xml of standardDoc.xml:

<standards>
    <stand startNum="5" endNum="5">19.A.4</stand>
    <stand startNum="11" endNum="11">14.D.2</stand>
    <stand startNum="11" endNum="11">14.D.3</stand>
    <stand startNum="13" endNum="14">14.A.2</stand>
    <stand startNum="15" endNum="15">14.A.1</stand>
    <stand startNum="16" endNum="16">14.A.1</stand>
....
</standards>

The following stylesheet works as far as it goes. It only captures the standards that match the start page of the lesson. What I need is way to address standards with startNum>= $localStart and<= $localEnd. Is there a way to do this using keys?

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

     <xsl:variable name="stand2page" select="document('stand2page.xml')"/>
     <xsl:key name="standPage" match="stand" use="@startNum"/>


<xsl:template match="Chapterlesson"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates/> <xsl:variable name="localStart" select="startNum"/> <xsl:variable name="localEnd" select="endNum"/> <xsl:for-each select="$stand2page"> <stand><xsl:copy-of select="key('standPage', $localStart)"/></stand> </xsl:for-each> </xsl:copy> </xsl:template>

Current Thread