You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT中使用preceding-sibling限制for-each,仅读取x=0元素前的内容?

Solution to Select Elements Before <line x="0.0"/>

Your current XSLT code has a couple of issues with the XPath logic that's preventing it from working correctly. Let's fix that and break down what's going on.

Correct XSLT Code (XSLT 1.0 Compatible)

Here's a working snippet that selects all elements inside <g id='NOCUT'> that appear before the first <line x="0.0"/>:

<xsl:template match="/">
  <!-- Target the specific g element first -->
  <xsl:for-each select="svg/g[@id='NOCUT']/*[not(preceding-sibling::line[@x='0.0'])]">
    <!-- Replace this with your processing logic -->
    <xsl:copy-of select="."/>
  </xsl:for-each>
</xsl:template>

Why Your Original Code Failed

Let's look at the key problems in your approach:

  • Incorrect Context in the Second for-each: When you use <xsl:for-each select="svg[g/@id='NOCUT']">, the context becomes the <svg> element. Your second for-each uses g/*, which would select all children of all <g> elements in the <svg>—but you should be targeting only the <g> with id='NOCUT' using *g[@id='NOCUT']/**.
  • Wrong Predicate Logic: The predicate *preceding-sibling::node[line/@x = '0.0']* is looking for a preceding sibling node that has a <line> child with x='0.0'. But the <line x="0.0"/> is a direct sibling element, not a child of another sibling node. Instead, you need to check if the current element does not have any preceding sibling <line> with x='0.0' (which is what *not(preceding-sibling::line[@x='0.0'])* does).

For XSLT 2.0+ Users (More Readable)

If you're using a processor that supports XSLT 2.0 or higher, you can use the *<<* operator (document order comparison) for a more intuitive query:

<xsl:template match="/">
  <xsl:variable name="target-line" select="svg/g[@id='NOCUT']/line[@x='0.0'][1]"/>
  <xsl:for-each select="svg/g[@id='NOCUT']/*[. << $target-line]">
    <!-- Your processing here -->
    <xsl:copy-of select="."/>
  </xsl:for-each>
</xsl:template>

This first stores the first occurrence of <line x="0.0"/> in a variable, then selects all elements that come before it in document order.

Edge Cases to Consider

  • If there's no <line x="0.0"/> in the <g id='NOCUT'>, both approaches will select all child elements of the <g>.
  • If there are multiple <line x="0.0"/> elements, both approaches will only select elements before the first occurrence (which is likely what you want).

内容的提问来源于stack exchange,提问作者HarsH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:57:49