Subject: RE: [xsl] document() merge DISTINCT From: "Chris Bayes" <chris@xxxxxxxxxxx> Date: Wed, 19 Dec 2001 16:17:56 -0000 |
I was testing using non unique ids because I didn't read your request right. So I was trying to keep the ids unique within a project. This should work <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="file" /> <xsl:variable name="root" select="/" /> <xsl:template match="/"> <p> <xsl:apply-templates select="/p/project" /> <xsl:copy-of select="document($file)/p/project[not(@name = current()/p/project/@name)]" /> </p> </xsl:template> <xsl:template match="project"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:copy-of select="*" /> <xsl:copy-of select="document($file)/p/project[@name = current()/@name]/person[not(@id = $root//@id)]" /> </xsl:copy> </xsl:template> </xsl:stylesheet> On this input <?xml version="1.0" ?> <p> <project name="some-name1"> <person id="1" name="name1"/> <person id="4" name="other-name"/> <person id="8" name ="another-name"/> </project> <project name="some-name2"> <person id="2" name="name1"/> <person id="5" name="other-name"/> <person id="9" name ="another-name"/> </project> <project name="some-name3"> <person id="3" name="name1"/> <person id="6" name="other-name"/> <person id="10" name ="another-name"/> <person id="13" name ="another-name"/> </project> </p> <?xml version="1.0" ?> <p> <project name="some-name1"> <person id="1" name="name1"/> <person id="4" name="other-name"/> <person id="8" name ="another-name"/> </project> <project name="some-name2"> <person id="2" name="name1"/> <person id="5" name="other-name"/> <person id="9" name ="another-name"/> </project> <project name="some-name3"> <person id="3" name="name1"/> <person id="6" name="other-name"/> <person id="10" name ="another-name"/> <person id="15" name ="another-name"/> </project> <project name="some-name4"> <person id="16" name="name1"/> <person id="20" name="other-name"/> <person id="24" name ="another-name"/> <person id="29" name ="another-name"/> </project> </p> Gives <?xml version="1.0" encoding="UTF-16"?> <p> <project name="some-name1"> <person id="1" name="name1" /> <person id="4" name="other-name" /> <person id="8" name="another-name" /> </project> <project name="some-name2"> <person id="2" name="name1" /> <person id="5" name="other-name" /> <person id="9" name="another-name" /> </project> <project name="some-name3"> <person id="3" name="name1" /> <person id="6" name="other-name" /> <person id="10" name="another-name" /> <person id="13" name="another-name" /> <person id="15" name="another-name" /> </project> <project name="some-name4"> <person id="16" name="name1" /> <person id="20" name="other-name" /> <person id="24" name="another-name" /> <person id="29" name="another-name" /> </project></p> If you just want a list of combined unique people then this will do it <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="file" /> <xsl:template match="/"> <p> <xsl:copy-of select="//person" /> <xsl:copy-of select="document($file)//person[not(@id = current()//@id)]" /> </p> </xsl:template> </xsl:stylesheet> The current function just changes context back to the source tree. If you didn't use it i.e. document($file)//person[not(@id = //@id)] would give you nothing because the context of //@id would be on the document() tree. This [@id = current()//@id] gives a set of all @ids that are the same and this [not(@id = current()//@id)] gives a set of all @ids that are different. Ciao Chris XML/XSL Portal http://www.bayes.co.uk/xml > -----Original Message----- > From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx > [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of > Alex Schuetz > Sent: 19 December 2001 12:35 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: Re: [xsl] document() merge DISTINCT > > > Hallo Chris, > > it does not work for me as expected.. > > I guess, I do not understand the meaning on current() in this context: > > To make it simpler for me, say I have more then two files I > want to merge > as: > > sample.xml: > <p> > <person name="name2" id="2"/> > <person name="name3" id="8"/> > <person name="name4" id="32"/> > </p> > > In each file all /person/@id are unique, but different files > might contain the same @id . Now I want to produce a list of > all <person> so that /person/@id is unique. > > As you suggested, I tried: > > <xsl:template match="person"> > <xsl:copy> > <xsl:copy-of > select="document($file)/p/person[not(@id = current()/p/person/@id]"/> > </xsl:copy> > </xsl:template> > > It looks to me, that [not(@id = current()/p/person/@id] is > always true and I get a list with non unique <person>. > > -Alex > > > > ----- Original Message ----- > From: "Chris Bayes" <chris@xxxxxxxxxxx> > To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> > Sent: Wednesday, December 19, 2001 12:30 PM > Subject: RE: [xsl] document() merge DISTINCT > > > > Alex, > > Something like this should do it > > <?xml version="1.0"?> > > <xsl:stylesheet version="1.0" > > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > > <xsl:param name="file" /> > > <xsl:template match="/"> > > <xsl:apply-templates select="/p/project" /> > > <xsl:copy-of select="document($file)/p/project[not(@name > > = current()/p/project/@name)]" /> > > </xsl:template> > > <xsl:template match="project"> > > <xsl:copy> > > <xsl:copy-of select="@*|*" /> > > <xsl:copy-of > > select="document($file)/p/project[@name = > > current()/@name]/person[not(@id = current()/person/@id)]" /> > > </xsl:copy> </xsl:template> > > </xsl:stylesheet> > > > > Ciao Chris > > > > XML/XSL Portal > > http://www.bayes.co.uk/xml > > > > > > > -----Original Message----- > > > From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx > > > [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of Alex > > > Schuetz > > > Sent: 19 December 2001 09:31 > > > To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx > > > Subject: [xsl] document() merge DISTINCT > > > > > > > > > Hallo; > > > > > > I have some input files with the /person/@id attribute > being unique > > > in each file (and /project). > > > > > > input.xml > > > -------------------------------------------------------------- > > > <project name="some-name"> > > > <person id="1" name="name1"/> > > > <person id="5" name="other-name"/> > > > <preson id="20" name ="another-name"/> > > > </project> > > > ------------------------------------------------ > > > > > > I want to merge these files so that I get a list of all <person> > > > that are in any <project> but the preson/@id should be > unique, that > > > is, no <person> element should be listed twice. > > > > > > In the book 'XSLT' from Dough Tidwell (chapter 7) there is an > > > example that works but is using a lot of disk reads and deep > > > recursion. It goes like this: > > > > > > 1: build a variable var1 as a white-space separated > sorted list of > > > all @id . (using <xsl:for-each select="document(...)"..../> ) > > > 2: build a variable var2 of unique @id from var1 (by recursion); > > > 3: with var2 call a template that calls <xsl:for-each select= > > > "document(....)"../> for each id in var2 and produces the output. > > > > > > Is there a better way to do this? > > > > > > -Alex > > > asc@xxxxxx > > > > > > > > > > > > > > > XSL-List info and archive: > > > http://www.mulberrytech.com/xsl/xsl-list > > > > > > > > > > > > XSL-List info and archive: > http://www.mulberrytech.com/xsl/xsl-list > > > > > > > XSL-List info > and archive: http://www.mulberrytech.com/xsl/xsl-list > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] document() merge DISTINCT, Jeni Tennison | Thread | Re: [xsl] document() merge DISTINCT, Alex Schuetz |
[xsl] with or without the root? [wa, Adriano Rodrigues Fe | Date | Re: [xsl] One nodeset, multiple bra, Wendell Piez |
Month |