Subject: Re: [xsl] document() merge DISTINCT From: "Alex Schuetz" <asc@xxxxxx> Date: Wed, 19 Dec 2001 18:12:48 +0100 |
Hi Chris, if I understand it right, your approach works if I want to merge two documents, that is, the argument for document() is just one file. What I want to do, is to merge more then two files at once. In this case it is not sufficant to compare the unique id to my source tree. I have to make sure, the id is unique for all files. Jeni Tennison suggestion makes sense to me.... -Alex ----- Original Message ----- From: "Chris Bayes" <chris@xxxxxxxxxxx> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Sent: Wednesday, December 19, 2001 5:17 PM Subject: RE: [xsl] document() merge DISTINCT > 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 > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] document() merge DISTINCT, Chris Bayes | Thread | RE: [xsl] document() merge DISTINCT, Chris Bayes |
Re: [xsl] Converting attributes to , Jeni Tennison | Date | [xsl] Parameter substitution, Curtis Burisch |
Month |