xsl-list
[Top] [All Lists]

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

2009-03-31 16:42:47
Emmanuel Begue schrieb am 31.03.2009 um 21:39:49 (+0200):

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>

If you dislike creating result tree fragments (as in the above variable
named "key") and are prepared to make some modifications to your input
document type and data (unlikely, but for the sake of the example, let's
assume that this is a realistic scenario), you can put to use a nice
idiom in XSLT 1.0 that combines the document() and the id() functions,
a nice idiom that has support in at least LibXSLT and Saxon and which
I've only just learnt about today.

Re: [xsl] AltovaXML and fragment identifier - Michael Ludwig (31.03.09)
http://markmail.org/message/6ad5trhfztlzior7

See modified input and XSLT below.

Michael Ludwig

C:\dev\XSLT :: type stresen-emailedstories.xml
<!DOCTYPE emails [
<!ATTLIST story id ID #IMPLIED>
]>
<!-- Note I added a DOCTYPE and defined an ID
     attribute in lieu of the id element. -->
<emails>
    <email>
        <!-- Unfortunately, an ID can't start with a number. -->
        <story id="X123"><!-- changed from 123 to X123 -->
        </story>
        <story id="ABC">
        </story>
    </email>
</emails>

C:\dev\XSLT :: type stresen-feedsource.xml
<atom:feed xmlns:atom="urn:x-Atom">
    <atom:entry>
        <atom:id>X123</atom:id><!-- changed accordingly -->
        <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>

C:\dev\XSLT :: more /t2 stresen-document-fragment-id.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
  xmlns:atom="urn:x-Atom"
  exclude-result-prefixes="atom"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:variable name="doc" select="'stresen-emailedstories.xml'"/>

  <xsl:template match="atom:feed">
    <xsl:copy>
      <xsl:apply-templates select="atom:entry"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="atom:entry">
    <xsl:variable name="uri" select="concat( $doc, '#', atom:id)"/>
    <uri><!-- show URI, just for fun -->
      <xsl:value-of select="$uri"/>
    </uri>
    <xsl:if test="not( document( $uri))"><!-- nice and simple -->
      <xsl:copy><xsl:apply-templates/></xsl:copy>
    </xsl:if>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>