[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Recursive function problem


Subject: Re: [xsl] Recursive function problem
From: Andrew Welch <andrew.j.welch@xxxxxxxxx>
Date: Wed, 30 Jun 2010 09:46:05 +0100

Wow that looks massively complicated for such a simple task!
Assuming its all necessary and just answering your initial quesion,
you have:

       <name>
           <xsl:copy-of select='@role'/>
           <xsl:value-of select='dtg:attributes-to-elements(.,
$name-attrs, $name-elems)'/>
       </name>

....and that value-of will always return a text node, so if your
function is returning elements you will get the text value of those
elements rather than the elements themselves.  If you change it to
xsl:copy-of instead of value-of you will get the elements.


cheers
andrew



On 30 June 2010 09:28, Nic Gibson <nicg@xxxxxxxxxx> wrote:
> Good morning
>
> I'm writing a function to be used as part of a content conversion from one
> DTD to another. The input is in the following form:
>
> <names>
>    <nameGrp role="editor" foreNames="Donald B."
>        mainName="Redford">Donald B. Redford</nameGrp>
>    <nameGrp
>        foreNames="Thutmose" foreTitle="III">Thutmose III</nameGrp>
> </names>
>
> and I need to get the output into the form:
>
> <names>
>    <name><fname>Donald B.</fname> <sname>Redford</sname></name>
>    <name><fname>Thutmose</fname> <ntitle>III</ntitle></name>
> </names>
>
> I've clearly made an error in the function as the output I am getting is
> on the lines of:
>
> <names>
>    <name>Donald B. Redford</name>
>    <name>Thutmose III</name>
> </names>
>
> The relevant portions of the stylesheet are:
>
> <xsl:stylesheet
>    xmlns:dtg="http://dtg.oup.com/functions"
>    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
>    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>    version="2.0" exclude-result-prefixes="dtg xd xs">
>
>    <xsl:variable name='name-attrs' select="('foreNames', 'mainName',
'foreTitle')"/>
>    <xsl:variable name='name-elems' select="('fname', 'sname', 'ntitle')"/>
>
>    <xsl:template match="/">
>        <names>
>            <xsl:apply-templates select='names/nameGrp'/>
>        </names>
>    </xsl:template>
>
>    <xsl:template match='nameGrp'>
>        <name>
>            <xsl:copy-of select='@role'/>
>            <xsl:value-of select='dtg:attributes-to-elements(., $name-attrs,
$name-elems)'/>
>        </name>
>    </xsl:template>
>
>
>    <xsl:function name='dtg:attributes-to-elements'>
>
>        <xsl:param name="element"/>
>        <xsl:param name='attributes'/>
>        <xsl:param name='elements'/>
>
>        <!-- only the listed attributes, not all of them -->
>        <xsl:variable name="attribs" select='$element/@*[local-name(.) =
$attributes]'></xsl:variable>
>
>        <!-- we want the attributes reverse sorted by the length of their
values. -->
>        <xsl:variable name='sorted-attribs' as='item()*'>
>            <xsl:perform-sort select='$attribs' >
>                <xsl:sort select='string-length(string(.))'
order="descending"/>
>            </xsl:perform-sort>
>        </xsl:variable>
>
>        <xsl:if test='count($attributes) != count($elements)'>
>            <xsl:message terminate="yes">attributes-to-elements - attribute
and element sequences must be the same size.</xsl:message>
>        </xsl:if>
>
>        <xsl:value-of select='dtg:attr-to-elem-impl(string($element),
$sorted-attribs, $attributes, $elements)'/>
>
>    </xsl:function>
>
>
>    <xsl:function name="dtg:attr-to-elem-impl">
>
>        <xsl:param name='source'/>
>        <xsl:param name='input-attribs'/>
>        <xsl:param name='attrib-names'/>
>        <xsl:param name='element-names'/>
>
>        <xsl:variable name='current-val'
select='string($input-attribs[1])'/>
>        <xsl:variable name='current-name'
select='local-name($input-attribs[1])'/>
>        <xsl:variable name='index' select='index-of($attrib-names,
$current-name)'/>
>        <xsl:variable name='output-element'
select='$element-names[$index]'/>
>        <xsl:variable name="next-attribs" select='$input-attribs[position()
gt 1]'/>
>
>        <xsl:choose>
>
>            <xsl:when test="$source = ''">
>                <xsl:value-of select="$source"/>
>            </xsl:when>
>
>            <xsl:when test="count($input-attribs) = 0">
>                <xsl:value-of select="$source"/>
>            </xsl:when>
>
>            <xsl:when test="contains($source, $current-val)">
>
>                <xsl:variable name='new-element'>
>                    <xsl:element name="{$output-element}"><xsl:value-of
select="$current-val"/></xsl:element>
>                </xsl:variable>
>
>                <xsl:variable name='before' select="substring-before($source,
$current-val)"/>
>                <xsl:variable name='after' select="substring-after($source,
$current-val)"/>
>
>                <xsl:variable name='result-before'
>                    select="dtg:attr-to-elem-impl($before, $next-attribs,
$attrib-names, $element-names)"/>
>                <xsl:variable name='result-after'
>                    select="dtg:attr-to-elem-impl($after, $next-attribs,
$attrib-names, $element-names)"/>
>
>                <xsl:sequence select="($result-before, $new-element,
$result-after)"/>
>
>            </xsl:when>
>
>            <xsl:otherwise>
>                <xsl:sequence select="dtg:attr-to-elem-impl($source,
$next-attribs, $attrib-names, $element-names)"/>
>            </xsl:otherwise>
>
>        </xsl:choose>
>
>    </xsl:function>
>
> </xsl:stylesheet>
>
> The large number of variables is due to my having traced through this in the
oXygen debugger.
> I've seen (in the degugger) that $new-element does contain the element
created but it
> appears to be lost before the result is generated.
>
> I'm pretty sure the error is in either the variable (new-element) that
should be
> creating the element or in the xsl:sequence instructions. However, I'm
having a failing
> to see the wood for the trees moment. Any pointers would be gratefully
received.
>
> By the way the recursion for result-before and result-after shoudl be safe
as I know
> that the content of each attribute can only occur once in the text.
>
> cheers
>
> nic
>
>



--
Andrew Welch
http://andrewjwelch.com
Kernow: http://kernowforsaxon.sf.net/


Current Thread
Keywords