xsl-list
[Top] [All Lists]

Re: [xsl] counting with position()

2010-01-05 15:35:46
Isn't that overly complicated, in general?

And is this actual code that outputs 1 product element as you stated?
> <xsl:template match="level2">
> <xsl:if test="following-sibling::*[1][self::product[preceding-sibling::*[1][self::item] There is no following-sibling to level2. Maybe you intended to match level2/item and test some conditions about its following-siblings. Then your level2 template should copy level2 and apply-templates to ./item only. But this code still won't yield the quoted results.

I'm trying to guess what you want to achieve from this inner code.
>                                        <xsl:variable name="count"
> select="count(./following-sibling::product[position()!=last()])"/>
>                                        <xsl:if test="$count>= 1">
>                                                <xsl:apply-templates
> select="./following-sibling::product[position() &lt; $count]"/>
>                                        </xsl:if>

Is it:
- $count is set to the number of products after item (not counting the last product though). In your case it should be 2. - If count is greater than or equal to 1, then the products whose position() is less than $count should be subject to apply-templates. In your example, this will be the first product.
?

This may be achieved by this snippet:

  <xsl:template
    match="level2/product[
             preceding-sibling::item
             and
             (: All products before this one but after the
                immediately precedent item must also be products:)
             (
               every $p in preceding-sibling::*[
                 . &gt;&gt; preceding-sibling::item[1]
               ] satisfies $p/self::product
             )
             and
             (: All following siblings before level3 must also be
                products.  If there's no level3 then the every
                expression evals to true() :)
             (
               every $f in following-sibling::*[
                 . &lt;&lt; following-sibling::level3[1]
               ] satisfies $f/self::product
             )
           ][
             (: Restrict the result so far to all but the last
                two items - don't know if this is really what you want:)
             position() lt last() - 1
           ]
           ">
    <!-- Really only apply, not copy? -->
    <xsl:apply-templates />
  </xsl:template>

  <!-- Discard all other products: -->
  <xsl:template match="level2/product" priority="0"/>

  <!-- Everything else: identity -->
  <xsl:template match="@* | *" priority="-1">
    <xsl:copy>
      <xsl:apply-templates select="@* | * | text()" mode="#current" />
    </xsl:copy>
  </xsl:template>


But maybe you are looking for an xsl:for-each-group group-starting-with="item|level3", and then look at current-group()[1] whether it's item, and then process the rest of current-group() if it consists of products only?

Gerrit





--~------------------------------------------------------------------
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>
--~--