选择每个节点和兄弟姐妹直到下一次出现

时间:2018-05-24 08:24:24

标签: xslt xslt-1.0 xslt-grouping

使用这个xml结构:

<doc>
    <members>
    <member name="T:XXX">
    </member>
    <member name="F:YYY">
    </member>
    <member name="P:ZZZ">
    </member>
    <member name="T:XXX">
    </member>
</doc>

我尝试让所有节点跟随节点,其名称属性以“ T:”开头,直到名称属性以“ T:”开头的下一个节点。

根据这个stackoverflow主题(#40767321),我发现了一个几乎完美的答案。

使用下面的 xsl:key ,它需要第一个 T:节点和所有关注者,但它还包含下一个 T:选择中的节点。 我怎么能把它排除在外呢?

<xsl:key name="subMembers" match="member" use="generate-id(preceding-sibling::*[contains(@name, 'T:')][1])" />

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

在链接主题中,该主题处理ol元素后跟div个元素,其关键字仅匹配div个元素。但是,在您的问题中, T:节点代表ol元素,并且键与这些元素匹配。

您需要更换密钥才能忽略 T:节点

<xsl:key name="subMembers" match="member[not(starts-with(@name, 'T:'))]" use="generate-id(preceding-sibling::*[starts-with(@name, 'T:')][1])" />

因此,假设您从选择 T:节点开始,您将选择这些节点和相关节点,如下所示:

 <xsl:copy-of select="self::*|key('subMembers', generate-id())" />

(或者,如果您还希望转换组元素,则可以使用xsl:for-eachxsl:apply-templates

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="subMembers" match="member[not(starts-with(@name, 'T:'))]" use="generate-id(preceding-sibling::*[starts-with(@name, 'T:')][1])" />

<xsl:template match="members">
    <members>
        <xsl:for-each select="member[starts-with(@name, 'T:')]">
            <group>
                <xsl:copy-of select="self::*|key('subMembers', generate-id())" />
            </group>
        </xsl:for-each>
    </members>
</xsl:template>

</xsl:stylesheet>