Re: [xsl] keys and idrefs

Subject: Re: [xsl] keys and idrefs
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Fri, 05 Oct 2001 11:31:02 -0400
Hi Dave,

Using keys,

With XML such as
 <process id="schemaDesign" layer="datalayer" control="XAG
systemArchitecture" input="systemSpec ">
    <name>Schema Design</name>
      </process>

and lots of similar,

then lots of <document elements>

   <document id="XAG" layer="WAI" >
        <name>XML Guidelines</name>
      </document>


I.e. the idrefs (control attribute on <process>) point to the controlling documents.

I'm trying to present the list of processes controlled by the document in an
html para.

So you want process elements back, using @control:


<xsl:key name="processes-by-control" match="process" use="@control"/>

High-level aside: I think the hardest thing about using a key is getting the right key defined, and I find the easiest way to define the right key is to find a name for it that describes what it is (hey I'm a poet not a mathematician). I also find the English preposition "by" to be very useful here because it encapsulates how key relationships work -- you're getting something back by means of something else related to it. The something you get back is the match pattern; the something else you're using is the use expression. So my key names are commonly "x-by-y" where x is the pattern, y is the use expression. Makes it easier to think through (and to understand the code).

in the template for 'document' I'm using the hack

  <xsl:template match="document">
      <xsl:variable name="thisDoc" select="@id"/>
.....
 <p> Controls:
              <xsl:for-each
select="id(//process|//document[@control='$thisDoc'])">
                <a href="{@id}.html"> <xsl:value-of select="name"/>
</a>&#160;
              </xsl:for-each>
            </p>

So you'd have <xsl:for-each select="key('processes-by-control', @id)"> ...

to get back all process elements whose @control attribute is the same as the @id attribute of the context node.

But I'm a bit confused by your expression "id(//process|//document[@control='$thisDoc'])". This reads to me as though you'll get all elements whose attribute of type ID is the same as the *content* of any <process> element or of any <document> element with @control = '$thisdoc' (the string, not the variable) ... stressing "content" because a node-set argument to the id() function acts as though giving it a set of strings. I don't think this'll work.

Since you want <process> elements back and @control on each process is an IDREF, not an ID, I think you have to use keys; the id() function only goes the other way.

If I'm not reading the requirement right, more clarification?

Cheers,
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================


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



Current Thread