-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxco-rdesc.xqm
142 lines (135 loc) · 6.58 KB
/
xco-rdesc.xqm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
(:
: xco-resc - functions creating rdesc component descriptors
:)
module namespace rd="http://www.parsqube.de/ns/xco/rdesc";
import module namespace cd="http://www.parsqube.de/ns/xco/desc"
at "xco-desc.xqm";
import module namespace cn="http://www.parsqube.de/ns/xco/comp-names"
at "xco-comp-names.xqm";
import module namespace co="http://www.parsqube.de/ns/xco/constants"
at "xco-constants.xqm";
import module namespace ns="http://www.parsqube.de/ns/xco/namespace"
at "xco-namespace.xqm";
declare namespace z="http://www.parsqube.de/ns/xco/structure";
(:~
: Returns for each given schema component the component descriptor
: and the component descriptors of all other schema components on
: which the given component depends.
:
: Input schema components may be global element declarations, type
: definitions and group definitions.
:
: A component depends on another comonent if it directly or indirectly
: references it (base type reference, group reference, attribute group
: reference).
:
: The descriptors of components which the given component depends
: are arranged in a map, using the component kind as keys (group,
: attributeGroup, element, attribute, type, localtype).
:
: @param comps schema components
: @return component descriptors of those components, and of those
: components on which they depend
:)
declare function rd:getRequiredCompDescs($comps as element()*,
$nsmap as element(z:nsMap),
$schemas as element(xs:schema)*,
$options as map(xs:string, item()*))
as map(xs:string, item()*) {
let $options := map:put($options, 'deepResolve', false())
for $comp in $comps
let $compDescs := rd:getRequiredCompDescsREC($comp, (), $nsmap, $schemas, $options)
let $requiredRaw := $compDescs => tail()
let $required :=
if (empty($requiredRaw)) then () else
(: Arrange the required descriptors in a map :)
let $groups := $requiredRaw/self::z:group
let $attributeGroups := $requiredRaw/self::z:attributeGroup
let $elems := $requiredRaw/self::z:element
let $atts := $requiredRaw/self::z:attribute
let $types := $requiredRaw/(self::z:simpleType, self::z:complexType)[@z:name]
let $localTypes := $requiredRaw/(self::z:simpleType, self::z:complexType)[@z:typeID]
return map:merge((
map:entry('group', $groups)[$groups],
map:entry('attributeGroup', $attributeGroups)[$attributeGroups],
map:entry('element', $elems)[$elems],
map:entry('attribute', $atts)[$atts],
map:entry('type', $types)[$types],
map:entry('localType', $localTypes)[$localTypes]
))
return
map{'main': $compDescs => head(),
'required': $required}
};
(:~
: Recursive helper function of `rd:getRequiredCompDescs`.
:
: @param comps schema components
: @param namesAvailable the qualified names of component descriptors already
: collected
: @param nsmap a map of normalized namespace bindings
: @param schemas a set of schema elements
: @param options options controlling the processing
: @return component descriptors of the schema components, followed
: by the component descriptors on which the given components depend
:)
declare function rd:getRequiredCompDescsREC(
$comps as element()*,
$namesAvailable as map(xs:string, item()*)?,
$nsmap as element(z:nsMap),
$schemas as element(xs:schema)*,
$options as map(xs:string, item()*))
as element()* {
let $compDescs := cd:getCompDescs($comps, $nsmap, $options)
let $newNamesAvailable := cn:mergeCompNames(cn:getCompNames($comps), $namesAvailable)
let $requiredCompNamesRaw := rd:getRequiredCompNames($compDescs, $options)
let $requiredCompNames := cn:compNamesExcept($requiredCompNamesRaw, $newNamesAvailable)
let $requiredCompsMap := cn:resolveCompNames($requiredCompNames, $schemas, true())
let $requiredComps := $requiredCompsMap?*
return (
$compDescs,
if (empty($requiredComps)) then () else
rd:getRequiredCompDescsREC($requiredComps, $newNamesAvailable, $nsmap, $schemas, $options)
[$requiredComps]
)
};
(:~
: Returns the qualified names of components referenced by a set of component
: descriptors. The component names are returned as a map with component kinds
: as keys and a sequence of qualified component names as values.
:
: Component kinds used as keys: group, attributeGroup, element, attribute,
: type, localType.
:
: @param compDescs component descriptors
: @param options options controlling the processing
: @return a map of qualified component names
:)
declare function rd:getRequiredCompNames($compDescs as element()*,
$options as map(xs:string, item()*))
as map(xs:string, item()*) {
map:merge(
let $groupNames := $compDescs//z:group/@z:ref/resolve-QName(., ..)
let $attributeGroupNames := $compDescs//z:attributeGroup/@z:ref/resolve-QName(., ..)
let $elemNames := $compDescs//z:element/@z:ref/resolve-QName(., ..)
let $attNames := $compDescs//z:attribute/@z:ref/resolve-QName(., ..)
let $typeNames := (
$compDescs//@z:base/resolve-QName(., ..),
$compDescs//@z:itemType/resolve-QName(., ..),
for $memberTypes in $compDescs//@z:memberTypes return
tokenize($memberTypes) ! resolve-QName(., $memberTypes/..),
(: Deep resolving (content type names) dependent on $options?deepResolve ... :)
$compDescs//@z:type[$options?deepResolve]/resolve-QName(., ..))
[not(ns:isQNameBuiltin(.))]
=> distinct-values()
let $localTypeNames := $compDescs//@z:typeID
return (
map:entry('group', $groupNames)[exists($groupNames)],
map:entry('attributeGroup', $attributeGroupNames)[exists($attributeGroupNames)],
map:entry('element', $elemNames)[exists($elemNames)],
map:entry('attribute', $attNames)[exists($attNames)],
map:entry('type', $typeNames)[exists($typeNames)],
map:entry('localType', $localTypeNames)[exists($localTypeNames)]
)
)
};