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

Re: XML-to-XML recursive template handling

Subject: Re: XML-to-XML recursive template handling
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Fri, 09 Dec 2011 11:33:57 -0500
Re:  XML-to-XML recursive template handling
Dear Lynne,

I don't know the NLM tool, so I'm guessing a bit.

In general, however, with this sort of problem you have two choices:

1. Pipeline. Move the elements out of the fn-group (and perform other modifications) and then clean up (for example, removing an empty fn-group) in a separate process. This can be done either at the "macro" level (the entire document) or (in XSLT 2.0) the "micro" level (just the fn-group).

Or 2. Write your code to recognize an fn-group from which all fn elements will be moved, and not process it.

Your code shows signs that you are trying to achieve something like a micropipeline in XSLT 1.0. In simply cases (such as yours) this is not impossible, although it entails the XSLT 1.0 version of (as it were) standing on your hands.

So one thing to consider is whether you can't modify your general approach; either use XSLT 2.0, or use a pipeline processor (such as XProc) or pipeline the old-fashioned way (pipeline the entire document not just the fn-group element). Having mastered these methods, this kind of problem will be much easier going forward.

Assuming you don't have the means or resources to do that, looking at your code, there are a couple of odd things:

<xsl:template match="fn-group">
  <xsl:param name="node"><xsl:apply-templates/></xsl:param>
  <!-- A parameter is declared and the results of applying templates
       to the children of the fn-group are bound to it.
       (Why a parameter? is this ever overridden from elsewhere?) -->

  <!-- Next, we copy the fn-group if it has fn children, and inside, we
       process the fn children -->
  <xsl:if test="fn">
    <fn-group>
      <xsl:for-each select="fn">
        <!-- code elided here. Each fn is either copied, or it isn't -->
      </xsl:for-each>
    </fn-group>

    <!-- next we call the emptyfn template, passing $node in -->
    <xsl:call-template name="emptyfn">
      <xsl:with-param name="node" select="$node"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

<xsl:template name="emptyfn">
  <!-- but 'emptyfn' is a no-op. If $node tests true, it ...
       does nothing -->
  <xsl:param name="node"/>
  <xsl:if test="not($node)"/>
</xsl:template>

Remember I'm guessing a little, but what I think you want is something more like this:

<xsl:template match="fn-group">
  <xsl:variable name="fn-results">
    ... for-each logic goes here ... or do the same thing, more
    gracefully, with templates ...
  </xsl:variable>
  <xsl:if test="normalize-space($fn-results">
    <fn-group>
      <xsl:copy-of select="fn-results"/>
    </fn-group>
  </xsl:if>
</xsl:template>

This is effectively an XSLT 1.0 "poor man's" version of a proper micropipeline such as we could do in XSLT 2.0. Basically it processes the fn children of the fn-group and binds the results to a variable. The results are an XSLT 1.0 temporary tree: it either contains copies of the fn elements, or it doesn't (if there were none we wanted to copy).

If the latter, the temporary tree will be cast to an empty string by the normalize-space() test in the subsequent xsl:if, and no fn-group will be created. If the set of fn elements resulted in non-whitespace content, however, this tests true, and they are copied in, inside an fn-group.

This might be all there is to it ... or maybe not, if there are details we have missed.

In XSLT 2.0 you could do the same thing, only more properly and more robustly. In particular, here the XSLT 1.0 has to make assumptions such as that the fn elements are going to have string values.

I hope this helps. Let us know.

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
======================================================================

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.