Subject: Re: [xsl] XSLT recursion problem From: "M. David Peterson" <m.david.x2x2x@xxxxxxxxx> Date: Wed, 28 Sep 2005 04:11:57 -0600 |
> group together child cousins, Uh, that would just be cousins... I started to write child and change my mind to cousin... helps if you delete the word you don't wan't, doesnt it :D On 9/28/05, M. David Peterson <m.david.x2x2x@xxxxxxxxx> wrote: > Actually, I misread your desired output... this actually elimates two > lines of code, but increases processing time because of crawling back > up the tree to get the value of the parents @element. But, its not a > huge deal unless you are processing heavy amounts of input where > performance is crucial... > > The updated code (still dependent on position... again, you need to > have something that make coding fun... having ALL the answers spoon > fed doesn't help you understand how it works, but having pieces of the > puzzle definitely helps... as such heres piece two of three pieces to > make this completely non dependent on the count of the parent elements > as well as increase performance by a decent chunk... keep in mind, > you're attempting to group together child cousins, in birth order... > grouping almost always points to a particular way of doing things... > > <?xml version="1.0" encoding="UTF-8"?> > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > xmlns:ax="uri:axnamespace" > version="1.0"> > <xsl:template match="/"> > <xsl:apply-templates select="ax:repeat/*" mode="initial"/> > </xsl:template> > <xsl:template match="*" mode="initial"> > <xsl:apply-templates select="*" mode="universal"> > <xsl:with-param name="name" select="name()"/> > </xsl:apply-templates> > </xsl:template> > <xsl:template match="*" mode="universal"> > <xsl:param name="name"/> > <xsl:variable name="position" select="position()"/> > <xsl:element name="{$name}"> > <xsl:apply-templates select="../*/*[position() = > $position]" mode="parent"/> > </xsl:element> > </xsl:template> > <xsl:template match="*" mode="parent"> > <xsl:param name="name"/> > <xsl:param name="parentName"/> > <xsl:element name="{$parentName}"> > <xsl:apply-templates select="." mode="child"> > <xsl:with-param name="name" select="$name"/> > </xsl:apply-templates> > </xsl:element> > </xsl:template> > <xsl:template match="*" mode="child"> > <xsl:element name="{parent::*/@element}"> > <xsl:copy-of select="@*"/> > </xsl:element> > </xsl:template> > </xsl:stylesheet> > > produces: > > <?xml version="1.0" encoding="utf-8"?> > <sometag> > <txt src="txt1.txt"/> > <img src="img1.jpg"/> > </sometag> > <sometag> > <txt src="txt2.txt"/> > <img src="img2.jpg"/> > </sometag> > > which is what you had in your sample... > > Enjoy! > > On 9/28/05, M. David Peterson <m.david.x2x2x@xxxxxxxxx> wrote: > > You can: > > > > In XSLT 1.0 this: > > > > <?xml version="1.0" encoding="UTF-8"?> > > <ax:repeat xmlns:ax="uri:axnamespace"> > > <sometag> > > <ax:items element="txt"> > > <ax:item src="txt1.txt"/> > > <ax:item src="txt2.txt"/> > > </ax:items> > > <ax:items element="img"> > > <ax:item src="img1.jpg"/> > > <ax:item src="img2.jpg"/> > > </ax:items> > > </sometag> > > </ax:repeat> > > > > Processed by this: > > > > > > <?xml version="1.0" encoding="UTF-8"?> > > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > > xmlns:ax="uri:axnamespace" > > version="1.0"> > > <xsl:template match="/"> > > <xsl:apply-templates select="ax:repeat/*" mode="initial"/> > > </xsl:template> > > <xsl:template match="*" mode="initial"> > > <xsl:apply-templates select="*" mode="universal"> > > <xsl:with-param name="name" select="name()"/> > > </xsl:apply-templates> > > </xsl:template> > > <xsl:template match="*" mode="universal"> > > <xsl:param name="name"/> > > <xsl:variable name="position" select="position()"/> > > <xsl:element name="{$name}"> > > <xsl:apply-templates select="../*/*[position() = > > $position]" mode="parent"> > > <xsl:with-param name="name" select="@element"/> > > </xsl:apply-templates> > > </xsl:element> > > </xsl:template> > > <xsl:template match="*" mode="parent"> > > <xsl:param name="name"/> > > <xsl:param name="parentName"/> > > <xsl:element name="{$parentName}"> > > <xsl:apply-templates select="." mode="child"> > > <xsl:with-param name="name" select="$name"/> > > </xsl:apply-templates> > > </xsl:element> > > </xsl:template> > > <xsl:template match="*" mode="child"> > > <xsl:param name="name"/> > > <xsl:element name="{$name}"> > > <xsl:copy-of select="@*"/> > > </xsl:element> > > </xsl:template> > > </xsl:stylesheet> > > > > = > > > > <?xml version="1.0" encoding="utf-8"?> > > <sometag> > > <txt src="txt1.txt"/> > > <txt src="img1.jpg"/> > > </sometag> > > <sometag> > > <img src="txt2.txt"/> > > <img src="img2.jpg"/> > > </sometag> > > > > This relies on the idea the child count and the parent count being > > exactly the same. Theres a way to write so this isn't the case but if > > we gave you all the answers you wouldnt have any fun :) > > > > As such, have fun :) > > > > > > On 9/28/05, Ragulf Pickaxe <ragulf.pickaxe@xxxxxxxxx> wrote: > > > > The real problem is that I don't want to have to know anything about > > > > <sometag>. That is, I would be free to use (and nest!) whatever > > > > non-proprietary tag inside my <repeat>, without modifing it. > > > > Probably there's no way in XSLT 1.0 (if it is, why creating tunnel in > > > > 2.0 ;) , but if you see another solution... > > > > > > > > > > Hi again Paolo, > > > > > > Why can you not have a general template for the "Sometag" and other > > > elements that you just want to pass on? > > > > > > I think that your own solution would be able to provide, if you change > > > the template that matches "Sometag" to the following: > > > > > > <xsl:template match="*"> > > > <xsl:param name="index" select="1"/> > > > <xsl:copy> > > > <xsl:copy-of select="@*"/> > > > <xsl:apply-templates> > > > <xsl:with-param name="index" select="$index"/> > > > </xsl:apply-templates> > > > <!-- sometag content --> > > > </xsl:copy> > > > </xsl:template> > > > > > > The match="ax:items" is more specific than match="*" and thus has > > > higher priority. > > > > > > My solution, I think, you would have to change three templates: > > > > > > <xsl:template match="ax:repeat"> > > > <xsl:apply-templates/> <!-- instead of <xsl:apply-templates > > > select="sometag"/>--> > > > </xsl:template> > > > > > > <xsl:template match="*"> <!-- Instead of <xsl:template match="sometag" --> > > > <xsl:copy> <!-- Copy element (shallow copy) --> > > > <xsl:copy-of select="@*"/> <!-- Copy all attributes --> > > > <!-- other non-proprietary elements to be processed: --> > > > <xsl:apply-templates select="*[not(self::ax:items)]"/> > > > <!-- Propriotary elements to be processed: --> > > > <xsl:apply-templates select="ax:items[1]" mode="first"/> > > > </xsl:copy> > > > </xsl:template> > > > > > > And remove the <sometag> and </sometag>from the > > > <xsl:template match="ax:items" mode="first"> > > > .. > > > </ > > > > > > > > > Is this what you need? > > > > > > Regards, > > > Ragulf Pickaxe :-) > > > > > > > > > > > > -- > > <M:D/> > > > > M. David Peterson > > http://www.xsltblog.com > > > > > -- > <M:D/> > > M. David Peterson > http://www.xsltblog.com > -- <M:D/> M. David Peterson http://www.xsltblog.com
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XSLT recursion problem, M. David Peterson | Thread | [xsl] XSLT Processors in .NET and S, António Mota |
Re: [xsl] XSLT recursion problem, M. David Peterson | Date | [xsl] Best default value for a resu, Nick Fitzsimons |
Month |