2011-03-11 67 views
2

测试前同胞和匹配后代我有一个问题,我相信我需要使用xsl:key来解决分组问题,但是我对正确的语法感到不知所措。对于下面的XML,当我处理每个<a/>元件我需要测试,以查看是否使用xsl:key

  1. 所述元件具有前同辈<markerStart/>元件和具有相同ID的后代</markerEnd>元件。

    • 通过“前同辈”我的意思是不能有当前元素和<markerStart/>之间的<a/>,如此显着<!-- # 5 -->应该返回假<a/>,而<a/><!-- # 1 -->和第一<a/>元素以下标记为<!-- # 2a -->应该返回true。
    • 通过“后裔”我的意思是必须不存在的<markerEnd/>之前<a/>后裔,所以<a/>标记<!-- # 0 -->和之后的元素标志着第<a/><!-- # 2b -->应该返回false。
  2. 或元素有后代<markerStart/>元素,并具有相同ID的后代</markerEnd>元素。

    • 通过“后裔”我的意思是必须不存在的<markerEnd/>之前<a/>后裔。

对于下面的XML,我希望打上<!-- # 1 --><!-- # 2a --><!-- # 4 -->节点返回true。

<root> 
    <a><!-- # 0 --> 
     <b> 
      <c> 
       <markerStart id="a1"/> 
       <a> <!-- # 1 --> 
        <b> 
         <c> 
         <markeEnd id="a1"/> 
         </c> 
        </b> 
       </a> 
       <markerStart id="a2"/><!-- # 2a --> 
       <markerStart id="a3"/><!-- # 2b --> 
       <a><!-- # 2 --> 
        <b> 
         <c> 
         <markeEnd id="a2"/> 
          <a><!-- # 3 --> 
           <b> 
            <c> 
             <markeEnd id="a3"/> 
            </c> 
           </b> 
          </a> 
         </c> 
        </b> 
       </a> 
       <markerStart id="a5"/> 
       <a><!-- # 4 --> 
        <markerStart id="a4"/> 
        <b> 
         <c> 
         <markeEnd id="a4"/> 
         </c> 
        </b> 
       </a> 
       <a><!-- # 5 --> 
        <b> 
         <c> 
         <markeEnd id="a5"/> 
         </c> 
        </b> 
       </a> 
      </c> 
     </b> 
    </a> 
</root> 

我需要为这个问题使用XSL 1.0。任何帮助都不胜感激。

+0

小澄清:''不是'A'元件。 – 2011-03-11 15:41:09

+0

@Alejandro:是的,在这种情况下,''是为了涉及''元素标有''的评论。在我试图澄清的时候,我知道我会把那个人弄糊涂了。 – Jacqueline 2011-03-11 16:30:10

+0

为什么最外层的'a'无法被选中? – 2011-03-11 16:54:51

回答

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

@Alejandro:对不起,我的描述不像我所希望的那样清晰,但“#0”不应该匹配。看到我上面的评论。 – Jacqueline 2011-03-11 17:12:14

+0

@Jacqueline:现在我终于明白了。检查我的更新。 – 2011-03-11 17:19:25

+0

+1 - 很好的答案。谢谢。 – Jacqueline 2011-03-11 18:23:40