[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Recursive function problem
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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|