使用xsl:key测试previous-sibling和匹配的后代

时间:2011-03-11 15:16:59

标签: xml xslt xpath

我有一个问题,我认为我需要使用xsl:key来解决分组问题,但我对正确的语法感到茫然。对于以下XML,当我处理每个<a/>元素时,我需要测试以查看是否

  1. 该元素具有前兄弟<markerStart/>元素和具有相同ID的后代</markerEnd>元素。

    • “previous-sibling”我的意思是当前元素和<a/>之间不能有<markerStart/>,因此标记为<a/>的{​​{1}}应返回false ,标记为<!-- # 5 -->的{​​{1}}和标记为<a/>的元素后的第一个<!-- # 1 -->应返回true。
    • “后代”我的意思是<a/>之前一定不能有<!-- # 2a -->后代,所以标记为<a/>的{​​{1}}和第一个<markerEnd/>标记为<a/>的元素后面应返回false。
  2. 或者该元素具有后代<!-- # 0 -->元素和具有相同ID的后代<a/>元素。

    • “后代”我的意思是<!-- # 2b -->之前一定不能有<markerStart/>后代。
  3. 对于以下XML,我希望标有</markerEnd><a/><markerEnd/>的节点返回true。

    <!-- # 1 -->

    我需要使用XSL 1.0来解决这个问题。任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:1)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kMarkerStartByFollowingMarkeEnd"
             match="markerStart"
             use="generate-id(following::markeEnd[1])"/>
    <xsl:key name="kMarkeEndByAncestorA"
             match="markeEnd"
             use="generate-id(ancestor::a[1])"/>
    <xsl:template match="a[key('kMarkeEndByAncestorA',
                               generate-id()
                           )[1]/@id =
                           key('kMarkerStartByFollowingMarkeEnd',
                               generate-id(key('kMarkeEndByAncestorA',
                                               generate-id()
                                           )[1])
                           )/@id]">
        <xsl:copy-of select="comment()"/>
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

输出:

<!-- # 1 --><!-- # 2 --><!-- # 4 -->