Я пытаюсь написать функцию в XQuery, которая возвращает мне метку времени из последовательности данных XML, если обнаружен определенный шаблон значений. Данные на самом деле являются тестовым журналом системных API-сообщений.
Пример XML-данных выглядит примерно так, как показано ниже. Если последовательность найдена, предполагается, что отметка времени (метка TIME) будет одинаковой для каждой строки записи шаблона.
Конкретный шаблон, который мне нужен для обнаружения и возврата TIME
из - это когда есть четыре записи <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>
в последовательности (т. е. в ВРЕМЯ 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)
};
<SEQUENCE>
не являются братьями и сестрами (это отдельные элементы в последовательности), поэтомуfollowing-sibling::
не будет работать. Чтобы сделать их братьями и сестрами, оберните их в родительский элемент, например.<root>
и уберите запятые между ними. - person LarsH   schedule 25.09.2012