Hi Rob,
Given this XML:
<foo>
<bar leftparen="((" rightparen="" num="3" oper="*" />
<bar leftparen="" rightparen=")" num="2" oper="-" />
<bar leftparen="" rightparen=")" num="2" />
</foo>
The following stylesheet:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/foo">
<foo>
<xsl:for-each select="bar[contains(@leftparen,'(')]">
<xsl:call-template name="XYZ">
<xsl:with-param name="elem" select="." />
<xsl:with-param name="x" select="string-length(@leftparen)" />
</xsl:call-template>
</xsl:for-each>
</foo>
</xsl:template>
<xsl:template name="XYZ">
<xsl:param name="elem" />
<xsl:param name="x" />
<paren>
<xsl:choose>
<xsl:when test="$x > 1">
<xsl:call-template name="XYZ">
<xsl:with-param name="elem" select="$elem" />
<xsl:with-param name="x" select="$x - 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{name($elem)}">
<xsl:copy-of select="$elem/@*[(name() != 'leftparen') and
(name() != 'rightparen')]" />
</xsl:element>
<xsl:call-template name="PQR">
<xsl:with-param name="nodeset"
select="$elem/following-sibling::bar" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</paren>
<xsl:if test="$x = 1">
<xsl:variable name="X"
select="$elem/following-sibling::bar[contains(following-sibling::*[1]/@leftparen,
'(') or not(following-sibling::*[1])]" />
<xsl:element name="{name($X)}">
<xsl:copy-of select="$X/@*[(name() != 'leftparen') and (name()
!= 'rightparen')]" />
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template name="PQR">
<xsl:param name="nodeset" />
<xsl:if test="($nodeset[1]/@leftparen = '') and
($nodeset[2]/@leftparen = '')">
<xsl:element name="{name($nodeset[1])}">
<xsl:copy-of select="$nodeset[1]/@*[(name() != 'leftparen') and
(name() != 'rightparen')]" />
</xsl:element>
<xsl:call-template name="PQR">
<xsl:with-param name="nodeset" select="$nodeset[position() > 1]" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
produces output:
<foo>
<paren>
<paren>
<bar num="3" oper="*"/>
<bar num="2" oper="-"/>
</paren>
<bar num="2"/>
</paren>
</foo>
(This is what you wanted)
I hope you can take this stylesheet as a starting point, and tinker with it.
Regards,
Mukul
On 7/3/06, Rob Allen <rallen3333(_at_)yahoo(_dot_)com> wrote:
Hello,
Is it possible to get XSLT to transform XML that looks
like this:
<foo>
<bar leftparen="((" rightparen="" num="3" oper="*"
/>
<bar leftparen="" rightparen=")" num="2" oper="-"
/>
<bar leftparen="" rightparen=")" num="2" />
</foo>
into something that looks like this:
<foo>
<paren>
<paren>
<bar num="3" oper="*"/>
<bar num="2" oper="-"/>
</paren>
<bar num="2"/>
</paren>
</foo>
"paren" elements are opened and closed based on the
number of '(' in each element's leftparen and
rightparen attributes.
Can anyone help?
Thanks,
Rob
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--