#xquery #basex
#xquery #basex
Вопрос:
<xs:attributeGroup name="personattr">
<xs:attribute name="attr1" type="xs:string"/>
<xs:attribute name="attr2" type="xs:integer"/>
<xs:attributeGroup ref="personattr2">
</xs:attributeGroup>
<xs:attributeGroup name="personattr2">
<xs:attribute name="attr12" type="xs:string"/>
<xs:attribute name="attr22" type="xs:integer"/>
<xs:attributeGroup ref="personattr3">
</xs:attributeGroup>
<xs:attributeGroup name="personattr3">
<xs:attribute name="attr13" type="xs:string"/>
<xs:attribute name="attr23" type="xs:integer"/>
</xs:attributeGroup>
<xs:attributeGroup name="personattr4">
<xs:attribute name="attr14" type="xs:string"/>
<xs:attribute name="attr24" type="xs:integer"/>
</xs:attributeGroup>
Учитывая приведенный выше пример файла XSD, как мне извлечь все вложенные attributeGroup, начиная с определенной attributeGroup? personattr
Оттуда есть personattr2
внутри. Внутри personattr2
есть personattr3
. Результат не должен содержать personattr4
.
Ответ №1:
Вы можете сделать это легко, перейдя к ссылочным дочерним группам с помощью рекурсивной пользовательской функции:
declare function local:groups-below($groups, $name) {
$name,
for $ref in $groups[@name = $name]/xs:attributeGroup/@ref/string()
return local:groups-below($groups, $ref)
};
local:groups-below($all-groups, 'personattr')
Это возвращает следующие имена групп:
personattr
personattr2
personattr3
Если вместо этого вам нужны целые элементы, просто верните их вместо их имен:
declare function local:groups-below($groups, $name) {
let $group := $groups[@name = $name]
return (
$group,
for $ref in $group/xs:attributeGroup/@ref/string()
return local:groups-below($groups, $ref)
)
};
local:groups-below($all-groups, 'personattr')
Это возвращает следующую последовательность:
<xs:attributeGroup xmlns:xs="http://www.w3.org/2001/XMLSchema" name="personattr">
<xs:attribute name="attr1" type="xs:string"/>
<xs:attribute name="attr2" type="xs:integer"/>
<xs:attributeGroup ref="personattr2"/>
</xs:attributeGroup>,
<xs:attributeGroup xmlns:xs="http://www.w3.org/2001/XMLSchema" name="personattr2">
<xs:attribute name="attr12" type="xs:string"/>
<xs:attribute name="attr22" type="xs:integer"/>
<xs:attributeGroup ref="personattr3"/>
</xs:attributeGroup>,
<xs:attributeGroup xmlns:xs="http://www.w3.org/2001/XMLSchema" name="personattr3">
<xs:attribute name="attr13" type="xs:string"/>
<xs:attribute name="attr23" type="xs:integer"/>
</xs:attributeGroup>
Комментарии:
1. Разве последняя строка не должна быть
local:groups-below(//attributeGroup, 'personattr')
?2. Входные данные, указанные в вопросе, не являются допустимым XML-узлом, поэтому я предположил, что это последовательность, привязанная к некоторой переменной (здесь
$all-groups
). Вам также нужны толькоxs:attributeGroup
элементы верхнего уровня, а не те, у@ref
которых есть атрибуты. Но если весь документ XSD является элементом контекста, тогдаlocal:groups-below(//xs:attributeGroup, 'personattr')
будет возвращен правильный результат.3. На самом деле я хочу, чтобы все узлы xs: attributeGroup возвращались в виде последовательности. В этом случае, attributeGroup с именем personattr, personattr2, personattr3 в последовательности. В любом случае я дам вам кредиты
4. Я расширил свой ответ, чтобы также показать, как вернуть сами
xs:attributeGroup
элементы.5. Я не понимаю ваш код. Функция local:groups-ниже возвращает последовательность. Разве конечный результат не является вложенной последовательностью, например (personattr, (personattr2, (personattr3)))?