3

我有一个这样的 xml 元素序列:

<addr>via roma</addr>
<addr>via milano</addr>
<addr>via napoli</addr>
...

我想检查是否存在包含相同连续地址 3 次或更多次的地址序列,例如:

<addr> via napoli</addr>
<addr>via roma</addr>
<addr>via roma</addr>
<addr>via roma</addr>
<addr>via milano</addr>
....

这个 xml 元素的输入序列是 xquery 的结果。我想我应该使用该fn:matches()函数,但我无法编写与该序列匹配的正则表达式。

4

3 回答 3

3

此查询(和 Xpath 3.0 表达式)true()恰好在序列$seq包含 $n 或更多具有相同字符串值的连续项时产生

    boolean($seq
              [some $i in 1 to count($seq) -($n -1)
                 satisfies
                    not(distinct-values(subsequence($seq, $i, $n))[2])
              ]
             )

因此,在这种特定情况下

let $n := 3,
    $seq := /*/addr
 return
        boolean($seq
                  [some $i in 1 to count($seq) -($n -1)
                     satisfies
                        not(distinct-values(subsequence($seq, $i, $n))[2])
                  ]
                 )

生产

true
于 2012-10-25T14:21:38.587 回答
2

不需要正则表达式。如果$addrs是一个addr元素序列,那么

for $a at $i in $addrs
  let $text := string($a)
  where string($addrs[($i + 1)]) eq $text and string($addrs[($i + 2)]) eq $text
  return ($i, $a)

为您提供三个相等的连续地址的子序列开始的元素和索引$addrs,在这种情况下(2, <addr>via roma</addr>)

请注意,当此类长度 >4 的子序列存在于$addrs.

于 2012-10-25T11:34:08.997 回答
1

使用正则表达式模式

<addr>([^<>]*)<\/addr>\s*<addr>\1<\/addr>\s*<addr>\1<\/addr>
于 2012-10-25T11:35:50.713 回答