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

Re: Spotting "cousin marriages" in a tree

Subject: Re: Spotting "cousin marriages" in a tree
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 29 Jul 2004 10:30:14 +0100
cousin tree
Hi Phil,

I think that you've covered the possible solutions here, so just a
couple of suggestions that might help you with the problems you
identified with this solution:

> I can do a multi-pass process using exsl:node-set(), generating the
> tree with the duplicates in it and then deleting them if they are
> duplicates, i.e. something like this:
[snip]
> There are two problems with this. First, generating the intermediate
> result could run forever if the input is seriously malformed (e.g. a
> loop, child refers to parent); checking as it is generated would
> avoid this.

You could avoid re-entry problems by keeping track of the ancestors of
a particular <tree> element through a parameter, something like:

<xsl:key name="things-by-id" match="thing" use="@id"/>

<xsl:template match="thing">
  <xsl:param name="ancestors" select="/.." />
  <tree>
    <xsl:for-each select="child">
      <xsl:choose>
        <xsl:when test="@idref = $ancestors">
          <error />
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="key('things-by-id',@idref)">
            <xsl:with-param name="ancestors"
                            select="$ancestors | @idref" />
          </xsl:apply-templates>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </tree>
</xsl:template>

> Second, the test "preceding::tree[@id=current/@id]" is O(n^2). Can I
> use a key to avoid this? How can a key be applied to an
> exsl:node-set() result?

In just the same way as you use keys with other documents. The key
returns nodes in the same document as the node you're on. It doesn't
make a difference that document has been generated from a result-tree
fragment. So you can do:

<xsl:key name="tree-by-id" match="tree" use="@id" />

<xsl:template match="tree" mode="remove-dupes">
   <xsl:choose>
     <xsl:when test="generate-id(key('tree-by-id', @id)[1]) !=
                     generate-id(.)">
       <error/>
     </xsl:when>
     <xsl:otherwise>
       <tree id="{@id}">
         <xsl:apply-templates mode="remove-dupes"/>
       </tree>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.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.