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(_dot_)ken(_dot_)holman(_at_)gmail(_dot_)com"
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
At 2016-11-05 16:19 +0000, Eliot Kimber ekimber(_at_)contrext(_dot_)com 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(_at_)CraneSoftwrights(_dot_)com |
Google+ blog _ _ _ _ _ http://plus.google.com/+GKenHolman-Crane/posts |
Legal business disclaimers: _ _ http://www.CraneSoftwrights.com/legal |
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--