[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] The solution (Was: Re: Design question)
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
|
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
|