[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Trying to match elements NOT found in external document


Subject: RE: [xsl] Trying to match elements NOT found in external document
From: Emmanuel Begue <eb@xxxxxxxxxx>
Date: Tue, 31 Mar 2009 21:39:49 +0200

Hello,

Given:

  <xsl:key name="id" match="*" use="id"/>
  <xsl:variable name="emailed" select="document('emailedstories.xml')"/>

in XSLT 2.0 you can do simply:

  <xsl:template match="atom:feed">
    <xsl:apply-templates
select="atom:entry[not(key('id',atom:id,$emailed))]"/>
    </xsl:template>

... and then a template that deals with atom:entry

The xsl:key matches any element and uses its id child(ren)
as reference; the key function has its context set by its
third element.

In XSLT 1.0 you need to set the context right; using the
same key and '$emailed' variable, you can do for example:

<xsl:template match="atom:feed">
	<xsl:for-each select="atom:entry">
		<xsl:variable name="id" select="atom:id"/>
		<xsl:variable name="key">
			<!-- setting the context to $emailed for key() -->
			<xsl:for-each select="$emailed/*">
				<xsl:copy-of select="key('id',$id)"/>
				</xsl:for-each>
			</xsl:variable>
		<xsl:if test="$key=''">
			<!-- the current atom:entry has no corresponding id in $emailed -->
			<xsl:apply-templates select="."/>
			</xsl:if>
		</xsl:for-each>
	</xsl:template>

Regards,
EB


> -----Original Message-----
> From: G. T. Stresen-Reuter [mailto:tedmasterweb@xxxxxxxxx]
> Sent: Tuesday, March 31, 2009 9:05 PM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Trying to match elements NOT found in external document
>
>
> Hi.
>
> It's been a while since I've written. I hope this email finds everyone
> doing well... on to business...
>
> I'm trying to match items in the source XML document that are NOT
> present in an external XML document.
>
> For example, Given the following XML documents I would like to match
> the atom:entry element whose atom:id = xyz by virtue of the fact that
> there is no corresponding email story with the same id.
>
> feedsource.xml
> <atom:feed>
>      <atom:entry>
>          <atom:id>123</atom:id>
>          <atom:title>Story 1</atom:title>
>      </atom:entry>
>      <atom:entry>
>          <atom:id>ABC</atom:id>
>          <atom:title>Story 2</atom:title>
>      </atom:entry>
>      <atom:entry>
>          <atom:id>xyz</atom:id>
>          <atom:title>Story 3</atom:title>
>      </atom:entry>
> </atom:feed>
>
> emailedstories.xml
> <emails>
>      <email>
>          <story>
>              <id>123</id>
>          </story>
>          <story>
>              <id>ABC</id>
>          </story>
>      </email>
> </emails>
>
> I've tried the following and in spite of the fact that most
> documentation states that keys include documents included via the
> document() function, I've been unable to verify that this is true.
> Here is the stylesheet I've tried to no avail:
>
>
> <xsl:key name="emailedstories" match="id" use="normalize-space(.)" />
>
> [...]
> <!-- there are many references to emailedstories.xml prior to the line
> below, for example -->
> <xsl:for-each select="document('../subscriptions/emailedstories.xml')/
> emails/email">
> [...]
>
> <!-- to select just the entry elements that are NOT in the
> emailedstories.xml file, I've been trying this -->
> <xsl:apply-templates select="atom:entry[count(key('emailedstories',
> atom:id)) = 0]" />
>
>
> This doesn't work. I suspect I'm confused about what the context node
> is and/or about comparing node sets vs. strings/numbers.
>
> Does anyone have any suggestions on how to do what I'm trying to do?
>
> Many thanks in advance!
>
> ----
>
> G. T. Stresen-Reuter
> Web: http://tedmasterweb.com
> Blog: http://tecnotertulia.com
> Twitter: http://twitter.com/tedmasterweb


Current Thread
Keywords