Другим вариантом является более функциональный подход к программированию.
Мы можем обобщить ваш тест в функцию, которая работает с theHoldingListsField
, поскольку она имеет только два инварианта: имя атрибута ($attr-name
) и код ошибки ($error-id
).
Мы в основном зацикливаем атрибуты (с кодами ошибок), которые вы хотите проверить, и вызываем функцию local:test
для каждого, например,
declare function local:test($theHoldingListsField, $attr-name, $error-id) {
$theHoldingListsField/@*[local-name() eq $attr-name][. ne "MANDATORY"] !
<error id="{$error-id}">
<args>
<arg value="{$theHoldingListsField/ancestor::node()/@id}"/>
<arg value="{$attr-name} = {.}"/>
</args>
<location value="{functx:path-to-node-with-pos($theHoldingListsField)}"/>
</error>
};
let $tests := (
["AFL", "DPR-CKSEM-DEP-SMF142-2"],
["attitudeIndicator", "DPR-CKSEM-DEP-SMF142-2"]
)
for $theHoldingListsField in //DisplaySettingCol/theDisplaySetting/theHoldingListsFields
let $test-fn := local:test($theHoldingListsField, ?, ?)
return
$tests ! fn:apply($test-fn, .)
В приведенном выше примере используются функции XQuery 3.1, такие как массивы ([]
), применение частичных функций (?
), оператор простого отображения (!
) и функции высшего порядка (fn:apply
) , Я бы посоветовал узнать об этом из спецификации XQuery 3.1 W3C.
Это также можно переписать, чтобы удалить for
, и вместо этого включить функцию local:test
для всех полей (т. Е. theHoldingListsFields
).