Re: [xsl] XSLT 2: Best Way to Synthesize Elements Given List of Tagnames

Subject: Re: [xsl] XSLT 2: Best Way to Synthesize Elements Given List of Tagnames
From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 5 Nov 2016 17:12:43 -0000
Here is my recursive solution, which actually takes the ancestor elements,
rather than the list of element types names (I need to copy attributes of
the ancestors):

<xsl:function name="local:makeWrapperElements" as="element()">
  <xsl:param name="ancestors" as="element()*"/>
  <xsl:param name="result" as="node()*"/>
 
  <xsl:choose>
    <xsl:when test="exists($ancestors)">
       <xsl:variable name="newResult" as="node()*">
         <xsl:element name="{name($ancestors[1])}">
           <xsl:sequence select="$ancestors[1]/@*"/>
           <xsl:sequence select="$result"/>
         </xsl:element>
       </xsl:variable>
       <xsl:sequence
select="local:makeWrapperElements($ancestors[position() gt 1], $newResult,
$doDebug)"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$result"/>
    </xsl:otherwise>
  </xsl:choose>
  </xsl:function>

Which I call like so:

<xsl:variable name="contents" as="node()*">
  <xsl:apply-templates ... />
</xsl:variable>
<xsl:variable name="ancestors" as="element()*"
    select="reverse(./ancestor::*[not(./descendant-or-self::*[df:class(.,
'task/step')])])"
/>
                    <xsl:sequence
select="local:makeWrapperElements($ancestors, $contents)"/>

In this case I'm operating on elements that are within DITA task steps and
only care about the ancestry between <step> and the element.

Please don't ask why I need to do this.


Cheers,


Eliot
--
Eliot Kimber
http://contrext.com
 






On 11/5/16, 11:46 AM, "G. Ken Holman g.ken.holman@xxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

>At 2016-11-05 16:19 +0000, Eliot Kimber ekimber@xxxxxxxxxxxx wrote:
>>Say I have this string: "foo/bar" (or any arbitrarily-long sequence of
>>/-delimited tag names) and want to construct from it:
>>
>><foo>
>>   <bar>
>>     <!-- Stuff added here that I get from somewhere else -->
>>   </bar>
>></foo>
>>
>>Is there an easier or more obvious way to generate this than an recursive
>>function?
>
>I think not.  Any function acting on the members of the sequence in
>sequence will finish a given member (thus closing out the element)
>before handling the next member.
>
>>With a recursive function I can easily create child elements until the
>>sequence is exhausted but it feels like there should be an easier way
>>using XSLT 2 but if there is I'm not thinking of it.
>
>I can't either, since you have to process the next member before
>finishing of any given member.  But that next member will have its
>own next member.
>
>Off the top I can't think of anything that isn't recursion.
>
>. . . . . . . . Ken
>
>
>--
>Check our site for free XML, XSLT, XSL-FO and UBL developer resources |
>Streaming hands-on XSLT/XPath 2 training @US$45: http://goo.gl/Dd9qBK |
>Crane Softwrights Ltd. _ _ _ _ _ _ http://www.CraneSoftwrights.com/s/ |
>G Ken Holman _ _ _ _ _ _ _ _ _ _ mailto:gkholman@xxxxxxxxxxxxxxxxxxxx |
>Google+ blog _ _ _ _ _ http://plus.google.com/+GKenHolman-Crane/posts |
>Legal business disclaimers: _ _ http://www.CraneSoftwrights.com/legal |

Current Thread