XSLT 2.0通过元素的第一次出现拆分current-group()
使用XSLT2.0,假设您有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]
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>