This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: document() merge DISTINCT


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@Bayes.co.uk>
To: <xsl-list@lists.mulberrytech.com>
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@lists.mulberrytech.com
> > [mailto:owner-xsl-list@lists.mulberrytech.com] On Behalf Of
> > Alex Schuetz
> > Sent: 19 December 2001 12:35
> > To: xsl-list@lists.mulberrytech.com
> > 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@Bayes.co.uk>
> > To: <xsl-list@lists.mulberrytech.com>
> > 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@lists.mulberrytech.com
> > > > [mailto:owner-xsl-list@lists.mulberrytech.com] On Behalf Of Alex
> > > > Schuetz
> > > > Sent: 19 December 2001 09:31
> > > > To: XSL-List@lists.mulberrytech.com
> > > > 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@ala.de
> > > >
> > > >
> > > >
> > > >
> > > >  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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]