我有一系列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()
函数,但我无法编写与此序列相匹配的正则表达式。
此Query(和XPATH 3.0表达式)在序列$seq
包含具有相同字符串值的$ n或更多的连续项目时,会完全产生true()
:
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
不需要正则表达式。如果$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时,您将获得重复的地址。
使用Regex模式
<addr>([^<>]*)</addr>s*<addr>1</addr>s*<addr>1</addr>