1

我需要一个 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>

如果是第一个,则可以有任意数量的此类元组。如果是第二个,则每种孩子可以有任意数量(包括零),并且顺序任意。

一只猫、一只狗、一匹马的特殊情况可以测试真假,以使算法更容易为准。

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


编辑。应 Dimitre 的要求,让我试着用另一种可能更简单的方式说出来。

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

4

2 回答 2

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。

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

于 2012-11-11T01:35:57.010 回答
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>

如果元组的顺序可以变化,则对于所有有 1 个或多个元组的顺序与元组的第一个实例相同的情况,此模板将返回 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>
于 2012-11-11T07:32:35.263 回答