OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

docbook-apps message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]


Subject: Re: DOCBOOK-APPS: DSSSL -> XSL


>>>>> "NW" == Norman Walsh <ndw@nwalsh.com> writes:

NW> Ah! It took a few minutes, but I figured it out :-) When you
NW> apply-templates in this template, you go back to the "default
NW> mode". (Modes aren't sticky in XSL.)

Thanks Norm,

Yep, I discovered that modes work differently in XSL than DSSSL,
although even if you carefully apply the modes in the `mode-d'
templates recursively, you don't get the expected behaviour.  

An even *more* significant difference seems to be that once in a mode
in XSL, that's where you stay, unless a further template explicitly
takes you out of it (note that this is in *contrast* to DSSSL where if
an element encountered in processing a subtree *isn't* explicity
defined inside that mode, you get the default, i.e. imported mode).

AL> <!-- template (1) --> 
AL> <xsl:template match="*" mode="programmer-info-mode"> 
AL>   <xsl:text>Running wildcard template for mode: </xsl:text><br/> 
AL> <xsl:apply-templates select="."/> 
AL> </xsl:template>

NW> So when corpauthor is encountered, you're no longer in
NW> programmer-info-mode.

Yep, I finally figured out that as well.  Note how this is quite
different to a DSSSL construction rule, because you don't need a
`default' rule, since if you process a node with in a particular mode,
you can still access the default rules if you haven't overriden them
by an XSL template.

So the DSSSL:

(element variablelist
  (let ((role (attribute-string (normalize "role"))))
    (if (equal? role "programmers")
        (with-mode programmer-info-mode
          (process-children))
        (process-children))))

(mode programmer-info-mode
  (element corpauthor
    (make sequence
      ($bold-italic-seq$ (literal "Group: "))
      (process-children)))
  (element fax
    (make sequence 
      ($italic-seq$ (literal "fax: "))
      (process-children))))

is not equivalent to the XSL (which you might reasonably expect to
duplicate the DSSSL output):

<xsl:template match="variablelist">
  <xsl:choose>
    <xsl:when test="@role='programmers'">
      <xsl:apply-templates mode="programmer-info-mode"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>Applying imports:</xsl:text><br/>
      <xsl:apply-imports/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="corpauthor" mode="programmer-info-mode"> 
  <b><i><xsl:text>Group: </xsl:text></i><b>
 <xsl:apply-templates select="." mode="programmer-info-mode"/> 
</xsl:template>

<xsl:template match="fax" mode="programmer-info-mode"> 
  <i><xsl:text>Fax: </xsl:text></i>
 <xsl:apply-templates select="." mode="programmer-info-mode"/> 
</xsl:template>

NW> The interesting thing is that if I change your xsl:include to
NW> xsl:import and change this to xsl:apply-imports, then it seems to
NW> work (at least in XT). I can't decide if I think this is a bug or
NW> a feature.

Interesting, I tried with various combinations of
xsl:include/xsl:import and nothing worked in the expected way.  In any
case I came up with (hopefully!) more elegant solution than my
original attempt, that avoids modes all together.  Here's what I
posted to the Mulberrytech XSL list:

Solution:
---------

Search for the all the desired nodes `corpauthor', `fax', `author' in
the following example that have as _ancestors_ (arbitrarily deep), a
`variablelist' with the appropriate attribute set, so I have templates
like the following:

  <!-- rules for role subclassing on programmer info pages -->
  <xsl:template match="variablelist[@role='programmers']//corpauthor">
    <strong><em>
      <xsl:text>Group: </xsl:text>
    </em></strong>
    <xsl:apply-templates/><br></br>
  </xsl:template>

  <xsl:template match="variablelist[@role='programmers']//fax">
    <em>fax: </em><xsl:apply-templates/><br></br>
  </xsl:template>

Perhaps not the most efficient in terms of the processing time (if
someone could suggest an alternative, faster way, I'd love to hear
about it), but the most elegant _I_ could come up with in XSL and
certainly the most isomorphic to (and arguably more succinct in terms
of number of lines than) the DSSSL equivalent:

(element variablelist
  (let ((role (attribute-string (normalize "role"))))
    (if (equal? role "programmers")
        (with-mode programmer-info-mode
          (process-children))
        (process-children))))

(mode programmer-info-mode
  (element corpauthor
    (make sequence
      ($bold-italic-seq$ (literal "Group: "))
      (process-children)))
  (element fax
    (make sequence 
      ($italic-seq$ (literal "fax: "))
      (process-children))))

Let me also say, coming from a DSSSL background it was less than
obvious how to solve this, since modes (although superficially
similar) function in fundamentally different ways in the two
languages.  

So I hope this belated followup helps others on the same migration
path.

Alex
-- 
Alex Lancaster * alexl@bigfoot.com * www.santafe.edu/~alex * 505 984-8800 x242


[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [Elist Home]


Powered by eList eXpress LLC