XSLT 2.0通过元素的第一次出现拆分current-group()

XSLT 2.0通过元素的第一次出现拆分current-group(),xslt,xslt-2.0,xslt-grouping,Xslt,Xslt 2.0,Xslt Grouping,使用XSLT2.0,假设您有current-group()={A,X,B,B,X},其中A,B和X是元素。什么是一种有效且易读的方法,可以在第一次出现B时将其拆分,以得到两个序列S1和S2,使得S1={A,X}和S2={B,B,X}?是否可以使用xsl:for-each-group构造来实现这一点 编辑:current-group()的元素不保证是同级元素,但保证按文档顺序排列 第一次尝试:对以 如果当前-group()的第一个B没有前面的同级B,则可以执行此操作。 我原以为位置谓词[1]

使用XSLT2.0,假设您有
current-group()
={A,X,B,B,X},其中A,B和X是元素。什么是一种有效且易读的方法,可以在第一次出现B时将其拆分,以得到两个序列S1和S2,使得S1={A,X}和S2={B,B,X}?是否可以使用xsl:for-each-group构造来实现这一点

编辑:
current-group()
的元素不保证是同级元素,但保证按文档顺序排列


第一次尝试:对以


如果当前-group()的第一个B没有前面的同级B,则可以执行此操作。 我原以为位置谓词
[1]
的作用域会限定在select子句中,因为
current-group()[self::B][1]
返回正确的B。我很想知道它为什么不这样作用域

XML


A1
B1-1
B1-2
A2
B2-1
B2-2
XSLT


结果


A1
B1-1
B1-2
A2
B2-1
B2-2

如您所见,第一组被正确拆分,但第二组没有。但是,如果将当前的-group()包装在父级中,然后将其传递给select子句,这将起作用,但这似乎效率低下。
functx
库定义了一个函数
functx:node的索引
():


商业版中的Saxon 10在之前有功能
项,在
中有功能
项,例如。如果需要,您可以自己滚动,但我不清楚您的输入,是否只要求在第一个
B
上拆分序列?该
B
的存在是否得到保证?您是否需要进一步拆分
B
s序列?对于元素是同级的输入,还是对于
A,X,B,B,X
的任何序列,也不清楚您是否要解决这一问题,这与它们在输入中的顺序/关系无关XML@MartinHonnen谢谢你的快速回复!无法确保
B
的存在。我不确定您所说的“进一步的
B
”是什么意思,在这种特殊情况下,组的元素总是按文档顺序排列,但不一定是同级的。
group start with=“B[1]”
在与模式
B[1]
匹配的任何项目上启动一个新组,并且该模式匹配任何
B
元素,该元素是其父元素的第一个
B
子元素;它与
select
序列中
B
的位置无关。
<xsl:function name="functx:index-of-node" as="xs:integer*"
              xmlns:functx="http://www.functx.com">
  <xsl:param name="nodes" as="node()*"/>
  <xsl:param name="nodeToFind" as="node()"/>

  <xsl:sequence select="
  for $seq in (1 to count($nodes))
  return $seq[$nodes[$seq] is $nodeToFind]
 "/>

</xsl:function>
<xsl:template match="root">
  <xsl:copy>
    <xsl:for-each-group select="*" group-starting-with="A">
        <xsl:variable name="pos" select="functx:index-of-node(current-group(), (current-group()[self::B])[1])"/>
        <S1>
            <xsl:copy-of select="current-group()[position() lt $pos]"/>
        </S1>
        <S2>
            <xsl:copy-of select="current-group()[position() ge $pos]"/>
        </S2>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:saxon="http://saxon.sf.net/"
    exclude-result-prefixes="#all" version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:output indent="yes"/>

    <xsl:template match="root">
        <xsl:copy>
            <xsl:for-each-group select="*" group-starting-with="A">
                <S1>
                    <xsl:apply-templates
                        select="saxon:items-before(current-group(), .{ . instance of element(B) })"/>
                </S1>
                <S2>
                    <xsl:apply-templates
                        select="saxon:items-from(current-group(), .{ . instance of element(B) })"/>
                </S2>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>