我有一个扁平的源结构,需要按以下条件分组:
元素P2可在P1后多次出现。 P1和所有以下P2元素直到下一次出现P1需要被分组为“位置”结构。当下一个P1元素出现时,“位置”会重复。
来源示例:
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
结果应为:
<Position>
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
</Position>
<Position>
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
</Position>
<Position>
<P1><field1/><field2/></P1>
<P2><field1/><field2/><field3/></P2>
<P2><field1/><field2/><field3/></P2>
</Position>
我正在尝试使用轴跟随兄弟,但无法弄清楚如何选择所有P2元素到P1的下一个出现。或者我应该在这种情况下使用xsl:key?
答案 0 :(得分:3)
在XSLT 2.0中,for-each-group
:
<xsl:for-each-group select="*" group-starting-with="P1">
<Position>
<xsl:copy-of select="current-group()" />
</Position>
</xsl:for-each-group>
在1.0中,我能想到的最有效的方法是定义一个键
<xsl:key name="P2key" match="P2" use="generate-id(preceding-sibling::P1[1])" />
将P2元素按最近的 P1分组。然后只处理P1元素并使用键拉出正确的P2:
<xsl:for-each select="P1">
<Position>
<xsl:copy-of select=". | key('P2key', generate-id())" />
</Position>
</xsl:for-each>
(我个人使用模板而不是for-each
但for-each
是一个更简单的例子)