xsd_schema/parser/frames/
schema.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7enum SchemaPhase {
8 Composition,
10 Components,
12}
13
14pub struct SchemaFrame {
16 phase: SchemaPhase,
17 target_namespace: Option<NameId>,
18 element_form_default: Option<String>,
19 attribute_form_default: Option<String>,
20 block_default: DerivationSet,
21 default_attributes: Option<QNameRef>,
22 xpath_default_namespace: Option<String>,
23 final_default: DerivationSet,
24 version: Option<String>,
25 default_open_content: Option<DefaultOpenContentResult>,
26 xml_lang: Option<String>,
27 id: Option<String>,
28 source: Option<SourceRef>,
29 annotations: Vec<Annotation>,
30 directives: Vec<DirectiveResult>,
31 components: Vec<FrameResult>,
32 foreign_attributes: Vec<ForeignAttribute>,
33 xml_namespace_id: Option<NameId>,
34 xml_lang_id: Option<NameId>,
35}
36
37impl SchemaFrame {
38 pub fn new(
39 attrs: &AttributeMap,
40 name_table: &NameTable,
41 source: Option<SourceRef>,
42 ns_snapshot: &NamespaceContextSnapshot,
43 ) -> SchemaResult<Self> {
44 let target_namespace = attrs
45 .get_value_by_name(name_table, "targetNamespace")
46 .map(|s| name_table.add(s));
47
48 validate_attr_value(attrs, name_table, "elementFormDefault", parse_form)?;
49 let element_form_default = attrs
50 .get_value_by_name(name_table, "elementFormDefault")
51 .map(String::from);
52
53 validate_attr_value(attrs, name_table, "attributeFormDefault", parse_form)?;
54 let attribute_form_default = attrs
55 .get_value_by_name(name_table, "attributeFormDefault")
56 .map(String::from);
57
58 let block_default = parse_derivation_set(
59 attrs.get_value_by_name(name_table, "blockDefault"),
60 )?;
61
62 let default_attributes = attrs
63 .get_value_by_name(name_table, "defaultAttributes")
64 .map(|s| parse_qname_ref(s, name_table, ns_snapshot))
65 .transpose()?;
66
67 #[cfg(feature = "xsd11")]
68 let xpath_default_namespace = attrs
69 .get_value_by_name(name_table, "xpathDefaultNamespace")
70 .map(String::from);
71 #[cfg(not(feature = "xsd11"))]
72 let xpath_default_namespace: Option<String> = None;
73
74 let final_default = parse_derivation_set(
75 attrs.get_value_by_name(name_table, "finalDefault"),
76 )?;
77
78 let version = attrs
79 .get_value_by_name(name_table, "version")
80 .map(String::from);
81
82 let id = attrs
83 .get_value_by_name(name_table, "id")
84 .map(String::from);
85
86 Ok(Self {
87 phase: SchemaPhase::Composition,
88 target_namespace,
89 element_form_default,
90 attribute_form_default,
91 block_default,
92 default_attributes,
93 xpath_default_namespace,
94 final_default,
95 version,
96 default_open_content: None,
97 xml_lang: None,
98 id,
99 source,
100 annotations: Vec::new(),
101 directives: Vec::new(),
102 components: Vec::new(),
103 foreign_attributes: Vec::new(),
104 xml_namespace_id: name_table.get(crate::namespace::XML_NAMESPACE),
105 xml_lang_id: name_table.get("lang"),
106 })
107 }
108}
109
110impl Frame for SchemaFrame {
111 fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
112 #[cfg(feature = "xsd11")]
113 let is_xsd11_element = matches!(
114 local_name,
115 xsd_names::OVERRIDE | xsd_names::DEFAULT_OPEN_CONTENT
116 );
117 #[cfg(not(feature = "xsd11"))]
118 let is_xsd11_element = false;
119
120 match self.phase {
121 SchemaPhase::Composition => matches!(
122 local_name,
123 xsd_names::INCLUDE
124 | xsd_names::IMPORT
125 | xsd_names::REDEFINE
126 | xsd_names::ANNOTATION
127 | xsd_names::SIMPLE_TYPE
128 | xsd_names::COMPLEX_TYPE
129 | xsd_names::ELEMENT
130 | xsd_names::ATTRIBUTE
131 | xsd_names::GROUP
132 | xsd_names::ATTRIBUTE_GROUP
133 | xsd_names::NOTATION
134 ) || is_xsd11_element,
135 SchemaPhase::Components => matches!(
136 local_name,
137 xsd_names::ANNOTATION
138 | xsd_names::SIMPLE_TYPE
139 | xsd_names::COMPLEX_TYPE
140 | xsd_names::ELEMENT
141 | xsd_names::ATTRIBUTE
142 | xsd_names::GROUP
143 | xsd_names::ATTRIBUTE_GROUP
144 | xsd_names::NOTATION
145 ),
146 }
147 }
148
149 fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
150 #[cfg(feature = "xsd11")]
151 if local_name == "xpathDefaultNamespace" {
152 return true;
153 }
154 matches!(
155 local_name,
156 "targetNamespace"
157 | "elementFormDefault"
158 | "attributeFormDefault"
159 | "blockDefault"
160 | "defaultAttributes"
161 | "finalDefault"
162 | "version"
163 | "id"
164 )
165 }
166
167 fn on_child_start(&mut self, local_name: &str, _name_table: &NameTable) {
168 if self.phase == SchemaPhase::Composition {
170 match local_name {
171 xsd_names::SIMPLE_TYPE
172 | xsd_names::COMPLEX_TYPE
173 | xsd_names::ELEMENT
174 | xsd_names::ATTRIBUTE
175 | xsd_names::GROUP
176 | xsd_names::ATTRIBUTE_GROUP
177 | xsd_names::NOTATION => {
178 self.phase = SchemaPhase::Components;
179 }
180 _ => {}
181 }
182 }
183 }
184
185 fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
186 match child {
187 FrameResult::Annotation(ann) => {
188 self.annotations.push(ann);
189 }
190 FrameResult::Directive(dir) => {
191 self.directives.push(dir);
192 }
193 FrameResult::Type(_)
194 | FrameResult::Element(_)
195 | FrameResult::Attribute(_)
196 | FrameResult::Group(_)
197 | FrameResult::Notation(_) => {
198 self.components.push(child);
199 }
200 FrameResult::DefaultOpenContent(doc) => {
201 self.default_open_content = Some(doc);
202 }
203 FrameResult::Skip => {}
204 _ => {}
205 }
206 Ok(())
207 }
208
209 fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
210 Ok(FrameResult::Schema(SchemaFrameResult {
211 target_namespace: self.target_namespace,
212 element_form_default: self.element_form_default,
213 attribute_form_default: self.attribute_form_default,
214 block_default: self.block_default,
215 default_attributes: self.default_attributes,
216 xpath_default_namespace: self.xpath_default_namespace,
217 final_default: self.final_default,
218 version: self.version,
219 default_open_content: self.default_open_content,
220 xml_lang: self.xml_lang,
221 id: self.id,
222 source: self.source,
223 annotations: self.annotations,
224 directives: self.directives,
225 components: self.components,
226 }))
227 }
228
229 fn children_are_top_level(&self) -> bool {
230 true
231 }
232
233 fn source(&self) -> Option<&SourceRef> {
234 self.source.as_ref()
235 }
236
237 fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
238 if let (Some(xml_ns), Some(lang_id)) = (self.xml_namespace_id, self.xml_lang_id) {
239 if let Some(attr) = attrs
240 .iter()
241 .find(|attr| attr.namespace == Some(xml_ns) && attr.local_name == lang_id)
242 {
243 self.xml_lang = Some(attr.value.clone());
244 }
245 }
246 self.foreign_attributes = attrs;
247 }
248}
249