我有一系列像这样的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()
函数,但我不能编写与此序列匹配的正则表达式。
答案 0 :(得分: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>)
。
请注意,$addrs
中存在长度> 4的子序列时,您将获得重复的地址。
答案 1 :(得分:2)
当序列true()
包含$ n或更多具有相同字符串值的连续项时,此查询(和Xpath 3.0表达式)产生$seq
:
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
答案 2 :(得分:1)
使用正则表达式
<addr>([^<>]*)<\/addr>\s*<addr>\1<\/addr>\s*<addr>\1<\/addr>