Thanks for your response.
The reason that I am testing if there is no following-sibling is
because there could be nested lists with product elements and I dont
want to match those.
So my input can look like this:
<level1>
<item>Sample</item>
<product>sample prod1</product>
<product>sample prod2</product>
<level2>
<item>Sample</item>
<product>sample prod11</product>
<product>sample prod12</product>
<product>sample prod13</product>
<level3>
<item>Sample</item>
<product>sample prod14</product>
<item>Sample</item>
</level3>
<item>Sample</item>
<product>sample prod15</product>
<product>sample prod16</product>
<item>Sample</item>
<level3>
<item>Sample</item>
</level3>
<product>sample prod17</product>
</level2>
<level1>
I only want to match sample prod1 and sample prod2 after <item> at level1.
You are right. My count is cutting out the last product which is NOT
what I intend. I want all product1 and 2 until the start of level2.
On Tue, Jan 5, 2010 at 3:34 PM, Imsieke, Gerrit, le-tex
<gerrit(_dot_)imsieke(_at_)le-tex(_dot_)de> wrote:
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() < $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::*[
. >> 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::*[
. << 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>
--~--
--~------------------------------------------------------------------
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>
--~--