[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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Recursive function problem, Nic Gibson | Thread | Re: [xsl] Recursive function proble, Nic Gibson |
[xsl] Recursive function problem, Nic Gibson | Date | Re: [xsl] Recursive function proble, Nic Gibson |
Month |
Keywords