不确定该描述是否最佳...但是给出了这个xml:
<?xml version="1.0"?>
<root>
<type1 num="1" first="1"/>
<type1 num="2" />
<type2 num="3" />
<type2 num="4" />
<type1 num="5" first="2"/>
<type1 num="6" />
<type2 num="7" />
<type2 num="8" />
<type1 num="9" first="3"/>
<type1 num="10" />
<type2 num="11" />
<type2 num="12" />
</root>
我想加深层次结构,并添加一个新的&#39;组&#39;每次我在一个type1节点序列中遇到第一个节点。 (注意:@first就是这样,我可以看到模板正在拾取的确切节点......我不想用它来启动组)
这是我的样式表。
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kFirstText" match="*" use="generate-id(preceding-sibling::type1[not(preceding-sibling::*[1][self::type1])][1])"/>
<xsl:template match="/">
<newroot>
<xsl:apply-templates/>
</newroot>
</xsl:template>
<xsl:template match="type1[not(preceding-sibling::*[1][self::type1])]">
<group>
<type1>
<xsl:copy-of select="@*"/>
<xsl:attribute name="first-in-group">true</xsl:attribute>
</type1>
<xsl:copy-of select="key('kFirstText', generate-id())"/>
</group>
</xsl:template>
</xsl:stylesheet>
我得到的结果是:
<?xml version='1.0' ?>
<newroot>
<group><type1 num="1" first="1" first-in-group="true"/><type1 num="2"/><type2 num="3"/><type2 num="4"/><type1 num="5" first="2"/></group>
<group><type1 num="5" first="2" first-in-group="true"/><type1 num="6"/><type2 num="7"/><type2 num="8"/><type1 num="9" first="3"/></group>
<group><type1 num="9" first="3" first-in-group="true"/><type1 num="10"/><type2 num="11"/><type2 num="12"/></group>
</newroot>
我发现this question让我非常接近,但正如您在输出中所看到的,type1节点的第一个实例在前两组中被复制。
我也意识到我对钥匙正在捡到的东西有点模糊。我的阅读是它正在拾取任何跟在前面没有类型1的type1的前一个实例之后的节点......就是这样吗?
我还试图在模板中使用相同的xpath排除@match中的那个节点(@num =&#34; 5&#34;),但这只是被忽略了。知道如何完成我上面描述的内容吗?
谢谢!
答案 0 :(得分:1)
以这种方式尝试:
<xsl:key name="kFirstText" match="*[not(self::type1[not(preceding-sibling::*[1][self::type1])])]" use="generate-id(preceding-sibling::type1[not(preceding-sibling::*[1][self::type1])][1])"/>
这排除了&#34;领导者&#34;来自密钥检索的组中的节点。