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

selecting every node and siblings until next occurrence

有了这个 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:[”开头的节点=28=]'.

基于这个Whosebug主题(),我找到了一个近乎完美的答案。

对于下面的 xsl:key,它需要第一个 T: 节点和所有跟随者,但它还包括下一个T: select 中的节点。 我怎样才能排除它?

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

因此,假设您从 selecting T: 节点开始,您将 select 这些节点和相关节点,就像这样:

 <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>