xsl-list
[Top] [All Lists]

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

2016-11-05 12:12:47
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
--~--

<Prev in Thread] Current Thread [Next in Thread>