开发者

How to interrupt an XSLT for-each loop for not contiguos elements?

开发者 https://www.devze.com 2023-04-07 17:05 出处:网络
I have a structured XML with this structure: <root> <item/> <开发者_如何学Go;item/>

I have a structured XML with this structure:

<root>
  <item/>
  <开发者_如何学Go;item/>
  <something/>
  <item/>
</root>

If I use something like this:

<xsl:for-each select="/root/item">

it will pick all the item elements inside the list. I want to interrupt the loop after the second item, because between the 2nd and the 3rd there is a something element.

How can I get this?


You can't actually break out of a xsl:for-each loop. You need to construct your loop so as to select only the elements you want in the first place.

In this case, you want to select all item elements which don't have a preceding sibling that isn't also an item element.

<xsl:for-each select="/root/item[not(preceding-sibling::*[not(self::item)])]"> 
   <xsl:value-of select="position()" />
</xsl:for-each>

When this is used, it should only select the first two item elements.


In XSLT there isn't any possibility for a "break" out of an <xsl:for-each> or out of <xsl:apply-templates>, except using <xsl:message terminate="yes"/> which you probably don't want. This is due to the fact that XSLT is a functional language and as in any functional language there isn't any concept of "order of execution" -- for example the code can be executing in parallel on all the nodes that are selected.

The solution is to specify in the select attribute an expression selecting exactly the wanted nodes.

Use:

<xsl:for-each select="/*/*[not(self::item)][1]/preceding-sibling::*">
 <!-- Processing here -->
</xsl:for-each>

This selects for processing all preceding elements siblings of the first child element of the top element that isn't item -- that means the starting group of adjacent item elements that are the first children of the top element.

0

精彩评论

暂无评论...
验证码 换一张
取 消