This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
The solution (Was: Re: Design question)
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Wed, 10 Jul 2002 10:51:13 -0700 (PDT)
- Subject: [xsl] The solution (Was: Re: Design question)
- Reply-to: xsl-list at lists dot mulberrytech dot com
Jay Burgess <jburgess at digarch dot com> wrote:
> I'm attempting to use XSL to transform XML to XML. The problem is
> that
> some child elements in the original XML are "attributes" of the new
> XML
> element, whereas other child "elements" are actually new child
> elements. That is:
>
> BEFORE:
> <test type="positive" name="Test 1">
> <param name="p1">123</param>
> <param name="date1">July 9</param>
> <param name="p2">false</param>
> </test>
>
> AFTER:
> <da:Positive name="Test 1" p1="123" p2="false">
> <da:Date number="1" value="July 9"/>
> </da:Positive>
>
> (Notice that p1 and p2 become attributes of the new element, but
> date1
> becomes a new child element.)
>
> From what I can tell, I need to accomplish the equivalent of the
> following, but haven't been able to come up with the way to do it:
>
> (1) Iterate through all original <param>s. For each <param> that will
> become an attribute, do <xsl:attribute>. For each <param> that will
> become a child element, store it off to the side in a node set of
> some
> sort.
>
> (2) When the iteration is complete, iterate through the node set
> built
> in (1), and do <xsl:element> on each.
>
> Is this the right way to solve this problem? If so, can someone
> provide
> some more detail, as nothing I've tried has worked. Or, is there a
> better way?
>
> Thanks in advance.
>
> Jay
Hi Jay,
As others have already pointed out, it is not possible to provide a
push-style solution.
However, a pull-style solution is quite straightforward:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="test">
<xsl:element name="{@type}">
<xsl:copy-of select="@*[name() != 'type']"/>
<xsl:apply-templates select="param[starts-with(@name,'p')]"/>
<xsl:apply-templates
select="param[not(starts-with(@name,'p'))]"/>
</xsl:element>
</xsl:template>
<xsl:template match="param[starts-with(@name,'p')]">
<xsl:attribute name="{@name}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="param[not(starts-with(@name,'p'))]">
<xsl:variable name="vDigits" select="'0123456789'"/>
<xsl:variable name="theName"
select="translate(@name,$vDigits, '')"/>
<xsl:element name="{$theName}">
<xsl:attribute name="number">
<xsl:value-of select="substring-after(@name, $theName)"/>
</xsl:attribute>
<xsl:attribute name="value">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This transformation, when applied on your source xml:
<test type="positive" name="Test 1">
<param name="p1">123</param>
<param name="date1">July 9</param>
<param name="p2">false</param>
</test>
produces this result:
<positive name="Test 1" p1="123" p2="false">
<date number="1" value="July 9"/>
</positive>
I have left as exercise some irrelevant things as the namespace and
capitalising the first character of the element name.
Hope this helps.
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
__________________________________________________
Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free
http://sbc.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list