Subject: Re: [xsl] Adding elements to unknown tree structure From: Mukul Gandhi <gandhi.mukul@xxxxxxxxx> Date: Sun, 25 Sep 2005 20:23:51 +0530 |
This looks like a grouping problem to me. You may use Muenchian grouping to solve this as shown below. <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" /> <xsl:key name="by-folder-name" match="folder" use="@name" /> <xsl:template match="/root"> <root> <xsl:for-each select="folder[generate-id() = generate-id(key('by-folder-name', @name)[1])]"> <folder name="{@name}"> <xsl:copy-of select="key('by-folder-name', @name)/*" /> </folder> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet> The XML file is <root> <folder name="documents"> <folder name="personal" /> </folder> <folder name="documents"> <folder name="public" /> </folder> </root> The output produced is <?xml version="1.0" encoding="UTF-8"?> <root> <folder name="documents"> <folder name="personal"/> <folder name="public"/> </folder> </root> This solution is not generic. But the concept might help. Regards, Mukul On 9/25/05, Gustave Stresen-Reuter <tedmasterweb@xxxxxxx> wrote: > Thanks for the pointers. I'm getting there, but have an interim > question. > > Given > > <folder name="documents"> > <folder name="personal" /> > <folder/> > <folder name="documents"> > <folder name="public"> > </folder> > > How do I get: > > <folder name="documents"> > <folder name="personal" /> > <folder name="public"> > </folder> > > The few places I've looked indicate that I should use something like > this: > > <xsl:copy-of select="not(@name = following::*/@name)" /> > > but that isn't working. Other things I've tried return the whole > document. Also, I'm afraid that this solution would not return the > name="public" child element of the second folder element. > > Basically, I'm looking for a "merged" version of these two fragments. > By "merged" I mean that if an element has the same ancestors, the same > attributes, and the attribute have the same values, but the node > content is different, the content should be added to the same node > appearing earlier in the document. > > Any ideas? > > Ted Stresen-Reuter > > On Sep 21, 2005, at 9:06 PM, Joris Gillis wrote: > > > Hi, > > > > Tempore 17:41:53, die 09/21/2005 AD, hinc in > > xsl-list@xxxxxxxxxxxxxxxxxxxxxx scripsit Gustave Stresen-Reuter > > <tedmasterweb@xxxxxxx>: > > > >> Given: > >> > >> <myxmlfile> > >> <folder name="root"> > >> <folder name="documents"> > >> <document name="passwords"> > >> 123456 > >> </document> > >> </folder> > >> <folder name="pictures"> > >> <folder name="family" /> > >> </folder> > >> </folder> > >> </myxmlfile> > >> > >> parameter: folder_name = "friends" > >> parameter: path2folder = root/pictures > >> > >> How can I create a new folder element named "friends" in the pictures > >> element? > >> > >> Keep in mind that I need to make sure that both "root" and "pictures" > >> exist and if they don't, create them first. > > > > See if you can get this stylesheet working: > > <xsl:stylesheet version="1.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <xsl:output method="xml" indent="yes"/> > > > > <xsl:template match="/"> > > <xsl:apply-templates> > > <xsl:with-param > > name="path2folder">/root/pictures/friends</xsl:with-param> > > </xsl:apply-templates> > > </xsl:template> > > > > <xsl:template match="node()"> > > <xsl:param name="path2folder"/> > > <xsl:param name="good" select="true()"/> > > <xsl:variable name="path" select="substring-before($path2folder,'/')"/> > > <xsl:variable name="verygood" > > select="($good and @name=$path) or self::myxmlfile"/> > > <xsl:variable name="pathafter" > > select="substring-after($path2folder,'/')"/> > > <xsl:variable name="nextpath" > > select="substring-before($pathafter,'/')"/> > > <xsl:variable name="folder" select="folder[@name=$nextpath][$good]"/> > > <xsl:copy> > > <xsl:copy-of select="@*"/> > > <xsl:apply-templates select="node()"> > > <xsl:with-param name="path2folder" select="$pathafter"/> > > <xsl:with-param name="good" select="$verygood"/> > > </xsl:apply-templates> > > <xsl:if test="$verygood and not($folder) and not($path2folder='')"> > > <xsl:call-template name="createFolder"> > > <xsl:with-param name="path2folder" select="$pathafter"/> > > </xsl:call-template> > > </xsl:if> > > </xsl:copy> > > </xsl:template> > > > > <xsl:template name="createFolder"> > > <xsl:param name="path2folder"/> > > <folder name="{substring-before(concat($path2folder,'/'),'/')}"> > > <xsl:if test="contains($path2folder,'/')"> > > <xsl:call-template name="createFolder"> > > <xsl:with-param name="path2folder" > > select="substring-after($path2folder,'/')"/> > > </xsl:call-template> > > </xsl:if> > > <xsl:if test="not(contains($path2folder,'/'))"> > > <xsl:comment>folder inserted</xsl:comment> > > </xsl:if> > > </folder> > > </xsl:template> > > > > </xsl:stylesheet> > > > > > > > > regards, > > -- > > Joris Gillis (http://users.telenet.be/root-jg/me.html) > > Don't send spam. I don't like it and it is illegal.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Adding elements to unknow, António Mota | Thread | Re: [xsl] Adding elements to unknow, Gustave Stresen-Reut |
[xsl] RELAX NG validator, Colin Paul Adams | Date | Re: [xsl] Adding elements to unknow, Gustave Stresen-Reut |
Month |