我试图在 XQuery 中编写一个函数,如果检测到特定的值模式,它会从 XML 数据序列中返回一个时间戳。数据实际上是一个系统的api消息的测试日志
示例 XML 数据类似于下面的代码片段。如果找到序列,则假定时间戳(TIME 标记)对于模式条目的每一行都是相同的。
我需要检测并返回TIME
of - 的特定模式是依次有四个<FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE>
条目,后跟四个<FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE>
条目 - 所有条目都具有相同的时间戳。
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>
<SEQUENCE><TIME>13.00</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>
<SEQUENCE><TIME>14.05</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>
<SEQUENCE><TIME>15.94</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>
<SEQUENCE><TIME>15.94</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>
我试图定义的函数如下,但会给出运行时错误'empty sequence not allowed'
。不幸的是,我没有可以设置断点并对其进行调试的 IDE——我想一旦我选择了一个带有FOR
.
declare function local:get_multi_track_sequence_time( $msgSeq as element()*) as xs:double {
for $row in $msgSeq
where some $entry in $row satisfies($entry/SEQUENCE[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::SEQUENCE[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI'] )
return data($row/SEQUENCE/TIME)
};
谢谢。我是 XQuery 的新手。
---------------------编辑 - 使用来自建议的想法添加测试功能-------------------- -
感谢您已经收到的建议。我根据给出的有用信息编写了以下自包含测试函数 - 该函数无法匹配后续兄弟的。
该函数创建一个data
包含测试序列的变量。就目前而言,该函数返回一个空序列。要求是它返回14.050000
以指示标量,在该标量TIME
处有四个<FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE>
按顺序排列的条目,紧随其后的是四个按顺序排列的条目(即在测试数据中的<FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE>
TIME )。14.050000
(有趣的是,如果只使用第一个表达式,即匹配所有出现的 TRACK_STATUS/VALID 没有指定后续兄弟匹配,它会成功返回一个双精度序列。)
declare function local:get_multi_track_sequence_time( ) as xs:double* {
let $data as element()* := (
<SEQUENCE><TIME>13.04080</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>13.04080</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>INVALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>13.05000</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>13.06900</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>,
<SEQUENCE><TIME>13.06900</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>TRACK_STATUS</FIELD><MODE>VALID</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>,
<SEQUENCE><TIME>14.05000</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>MULTI</MODE></SEQUENCE>,
<SEQUENCE><TIME>15.06700</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>,
<SEQUENCE><TIME>15.06700</TIME><TAG>2900</TAG><FIELD>MULTI_CHAN_IND</FIELD><MODE>SINGLE</MODE></SEQUENCE>
)
for $entry in $data
where $entry/self::SEQUENCE
[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='TRACK_STATUS' and MODE='VALID']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
/following-sibling::*[1]/self::SEQUENCE
[TAG='2900' and FIELD='MULTI_CHAN_IND' and MODE='MULTI']
return data($entry/TIME)
};