[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] XML-to-XML recursive template handling
Hi Wendell- Yes, your solution worked, and that is what I was moving toward; I just didn't quite know how to get there, and thought I needed to pass a parameter into a called template to accomplish it. Thank you! I do have access to an XSLT 2.0 processor, and can probably modify these stylesheets to use XSLT 2.0... For future reference, would you mind explaining what the more graceful XSLT 2.0 solution would be? Thanks again- Lynn Lynn Murdock, MLIS Web Producer Public Library of Science (PLoS) http://www.plos.org<http://www.plos.org/> On Dec 9, 2011, at 10:10 PM, <xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx<mailto:xsl-list-digest-help@list s.mulberrytech.com>> <xsl-list-digest-help@xxxxxxxxxxxxxxxxxxxxxx<mailto:xsl-list-digest-help@list s.mulberrytech.com>> wrote: Date: Fri, 09 Dec 2011 11:33:57 -0500 To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx<mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx> From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx<mailto:wapiez@xxxxxxxxxxxxxxxx>> Subject: Re: XML-to-XML recursive template handling Message-ID: <4EE23875.8060200@xxxxxxxxxxxxxxxx<mailto:4EE23875.8060200@xxxxxxxxxxxxxxxx>> 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<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 ====================================================================== ------------------------------ Date: Thu, 8 Dec 2011 21:50:11 -0800 To: "xsl-list@xxxxxxxxxxxxxxxxxxxxxx<mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx>" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx<mailto:xsl-list@xxxxxxxxxxxxxxxxxxxxxx>> From: Lynn Murdock <lmurdock@xxxxxxxx<mailto:lmurdock@xxxxxxxx>> Subject: XML-to-XML recursive template handling Message-ID: <91FE79B4-51AE-4F49-8C5A-055CE08F6614@xxxxxxxx<mailto:91FE79B4-51AE-4F49-8C5A -055CE08F6614@xxxxxxxx>> Hi- I am doing an XML-to-XML transform in which I need to rearrange elements in= such a way that sometimes the context element is left empty when I am fini= shed rearranging (but not always). As a second step, I want to strip these = newly empty elements from the final output, and I am having trouble doing s= o. For those of you who are familiar with the NLM's tool to convert older DTDs= to the 3.0 DTD, I am modifying the base.xsl component of the 2publishing3 = conversion. Essentially, everything is copied through except elements that = need to be modified in one way or another. Specifically, I am moving certai= n footnotes out of <fn-group> and into other locations in the document. If = the only footnotes in the original <fn-group> are those that I move, then a= fter this action, the result is <fn-group/>, which I want to remove from th= e final output. I've tried several methods, and nothing I've tried is working. Any pointers= would be very much appreciated. I think that the issue is that I'm not ful= ly understanding how the recursion works here to re-process a node that I'v= e already processed once (or maybe it has to do with the default copy metho= d for the stylesheet?)... (Default copy: <xsl:template match=3D"* | @* | text()" priority=3D"-1"> <xsl:copy> <xsl:apply-templates select=3D"@*|*|text()"/> </xsl:copy> </xsl:template>) XSL version=3D1.0 Processor=3DOxygen's built-in saxon (Oxygen version 11.2 for Linux) Here's the relevant section of the stylesheet: <xsl:template match=3D"fn-group"> <xsl:param name=3D"node"><xsl:apply-templates/></xsl:param> <xsl:if test=3D"fn"> <fn-group> <xsl:for-each select=3D"fn"> <xsl:choose> <!-- retag no fn-type to fn-type=3D"other" --> <xsl:when test=3D"not(@fn-type)"> <fn fn-type=3D"other"> <xsl:apply-templates/> </fn> </xsl:when> <xsl:when test=3D"@fn-type=3D'other'"> <fn fn-type=3D"other"> <xsl:apply-templates/> </fn> </xsl:when> <!-- suppress here, moved to author-notes --> <xsl:when test=3D"fn-type=3D'conflict'"/> <!-- suppress here, retagged into funding-statement --> <xsl:when test=3D"fn-type=3D'financial-disclosure'"/> </xsl:choose> </xsl:for-each> </fn-group> <xsl:call-template name=3D"emptyfn"> <xsl:with-param name=3D"node" select=3D"$node"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template name=3D"emptyfn"> <xsl:param name=3D"node"/> <xsl:if test=3D"not($node)"/> </xsl:template> Thanks much- Lynn Lynn Murdock, MLIS Web Producer Public Library of Science (PLoS) http://www.plos.org<http://www.plos.org/> Lynn Murdock, MLIS Web Producer Public Library of Science (PLoS) http://www.plos.org Lynn Murdock, MLIS Web Producer Public Library of Science (PLoS) http://www.plos.org
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|