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

Re: [xsl] Creating intermediate XML fragment


Subject: Re: [xsl] Creating intermediate XML fragment
From: Peter Davis <pdavis152@xxxxxxxxx>
Date: Wed, 18 Sep 2002 14:02:21 -0700

On Wednesday 18 September 2002 08:51, alexandre bord wrote:
> i'm sorry not to have explained it .
> The rules are
> (0) @name = name1 = @ name2
> (1) print foobar/@name if it is not ( in bar/@name1 or in bar/@name2 or
> in foo/@name)
> (2) print bar/@name1 if it is not in foo/@name
> (2') print bar/@name2 if it is not in foo/@name
> (3) Don't print foo/@name
>
> It's your second guess (i think)
> Thanks once more for your help

Okay, the answer is fairly simple then.  Like I said, it's a grouping problem.  
One of the ways to solve it is to use the Muenchian method to test that a 
value has not already been output (search through other threads on this list 
for more info about that method).

<!-- Make a key so that you can look up any of the name values -->
<xsl:key name="name" match="foobar/@name | bar/@name1 | bar/@name2" use="."/>

<!-- Make a key to lookup the foo/@name values -->
<xsl:key name="not-name" match="foo/@name" use="."/>

<!-- For each element, apply-templates on its attributes and its children, but 
don't output anything here -->
<xsl:template match="*">
  <xsl:apply-templates select="@*"/>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="foobar/@name | bar/@name1 | bar/@name2">
  <!-- if the name attribute is the first with the given value -->
  <xsl:if test="count(. | key('name', .)[1]) = 1">
    <!-- and if there are no foo/@name's with the value -->
    <xsl:if test="not(key('not-name', .))">
      <xsl:value-of select="."/>
      <xsl:text>&#10;</xsl:text>
    </xsl:if>
  </xsl:if>
</xsl:template>

<!-- for all other attributes, do nothing -->
<xsl:template match="@*"/>

-- 
Peter Davis

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread