用于检测子项是否交错的Xpath

时间:2012-11-11 00:17:35

标签: xslt

我需要一个XSLT 1.0测试表达式,它将指示当前节点t的元素是否完全交错,如下所示

<t>
    <cat />
    <dog />
    <horse />
    <cat />
    <dog />
    <horse />
</t>

或有其他订单,例如

<t>
    <cat />
    <cat />
    <dog />
    <dog />
    <horse />
    <horse />
</t>

<t>
    <cat />
    <dog />
    <cat/>
    <horse/>
    <cat/>
    <horse />
</t>

如果是第一个,那么可以有任意数量的这种元组。如果是第二个,那么每种类型的孩子可以有任何数量(包括零),也可以是任何顺序。

一只猫,一只狗,一匹马的特殊情况可以测试真假,无论哪种算法都更容易。

我事先知道这三个元素的名称。


EDIT。在Dimitre的要求下,让我试着说另一种,也许更简单的方式。

上下文节点具有任意数量的子节点,但每个子节点只有三个名称之一。在处理这些孩子之前,我需要测试它们是否以重复模式出现,例如ABCABCABC或CABCAB,或者重复三元组​​的任何其他组合,三元组中的每一个都出现一次(ABCABC测试为真,ABBABB测试为假)

2 个答案:

答案 0 :(得分:0)

test="name(*[last()])=name(*[3]) 
  and name(*[1])!=name(*[2])
  and name(*[2])!=name(*[3])
  and name(*[1])!=name(*[3])
  and not(*[position() > 3][name()!=name(preceding-sibling::*[3])])"
如果交错是完美的(或者如果只有三个项目),则

返回true。

编辑:添加第一个条件以确保最终元组完成,并确保重复元组的三个中间条件包括三个项目中的每一个(即,不包括重复项)。

答案 1 :(得分:0)

如果元组的顺序是固定的,那么对于有1个或更多元组的所有情况,此模板将返回true,否则返回false:

<xsl:template match="t">
  <xsl:sequence
    select="
    count(*) gt 2 and
    count(*) = count(*[
      self::cat   and position() mod 3 = 1 or
      self::dog   and position() mod 3 = 2 or
      self::horse and position() mod 3 = 0])"/>
</xsl:template>

如果元组的顺序可能不同,则对于所有情况,如果有一个或多个元组的顺序与元组的第一个实例相同,则此模板将返回true,否则返回false

<xsl:template match="t">
  <xsl:variable name="cat.pos"   select="(count(cat[1]/preceding-sibling::*) + 1)   mod 3"/>
  <xsl:variable name="dog.pos"   select="(count(dog[1]/preceding-sibling::*) + 1)   mod 3"/>
  <xsl:variable name="horse.pos" select="(count(horse[1]/preceding-sibling::*) + 1) mod 3"/>
  <xsl:sequence
    select="
    count(*) gt 2 and
    count(*) = count(*[
      self::cat   and position() mod 3 = $cat.pos or
      self::dog   and position() mod 3 = $dog.pos or
      self::horse and position() mod 3 = $horse.pos])"/>
</xsl:template>