lutaml-model 0.7.7 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1585) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-repos.json +9 -0
  3. data/.github/workflows/dependent-tests.yml +4 -0
  4. data/.github/workflows/docs.yml +59 -0
  5. data/.github/workflows/downstream-performance.yml +153 -0
  6. data/.github/workflows/performance.yml +33 -0
  7. data/.github/workflows/rake.yml +13 -0
  8. data/.github/workflows/release.yml +5 -0
  9. data/.gitignore +27 -1
  10. data/.rubocop.yml +14 -2
  11. data/.rubocop_todo.yml +408 -88
  12. data/Gemfile +15 -9
  13. data/README.adoc +13736 -6922
  14. data/RELEASE_NOTES.adoc +51 -0
  15. data/Rakefile +2 -0
  16. data/bench/baselines/.gitkeep +0 -0
  17. data/bench/bench_all.rb +52 -0
  18. data/bench/bench_common.rb +147 -0
  19. data/bench/bench_compare.rb +195 -0
  20. data/bench/bench_mml.rb +53 -0
  21. data/bench/bench_niso.rb +54 -0
  22. data/bench/bench_sts.rb +49 -0
  23. data/bench/bench_unitsml.rb +43 -0
  24. data/bench/bench_xmi.rb +51 -0
  25. data/bench/gate_config.rb +120 -0
  26. data/benchmark/quick_benchmark.rb +297 -0
  27. data/benchmark/serialization_benchmark.rb +619 -0
  28. data/docs/.rubocop.yml +1 -0
  29. data/docs/.rubocop_todo.yml +7 -0
  30. data/docs/Gemfile +13 -0
  31. data/docs/PERFORMANCE_METHODOLOGY.md +645 -0
  32. data/docs/_config.yml +145 -0
  33. data/docs/_guides/advanced-mapping.adoc +564 -0
  34. data/docs/_guides/character-encoding.adoc +342 -0
  35. data/docs/_guides/collection-serialization.adoc +349 -0
  36. data/docs/_guides/creating-xsd.adoc +1221 -0
  37. data/docs/_guides/index.adoc +71 -0
  38. data/docs/_guides/keyvalue-serialization.adoc +1156 -0
  39. data/docs/_guides/liquid-templates.adoc +505 -0
  40. data/docs/_guides/missing-values-handling.adoc +1531 -0
  41. data/docs/_guides/ooxml-examples.adoc +755 -0
  42. data/docs/{schema_generation.adoc → _guides/schema-generation.adoc} +5 -0
  43. data/docs/{schema_import.adoc → _guides/schema-import.adoc} +276 -4
  44. data/docs/_guides/value-transformations.adoc +1388 -0
  45. data/docs/_guides/xml/namespace-presentation.adoc +476 -0
  46. data/docs/_guides/xml/namespace-semantics.adoc +677 -0
  47. data/docs/_guides/xml/reusable-mapping-classes.adoc +181 -0
  48. data/docs/_guides/xml/schema-location.adoc +245 -0
  49. data/docs/_guides/xml/type-namespaces.adoc +1011 -0
  50. data/docs/_guides/xml-mapping.adoc +1847 -0
  51. data/docs/_guides/xml-mappings-guide.adoc +21 -0
  52. data/docs/_guides/xml-namespace-declarations.adoc +662 -0
  53. data/docs/_guides/xml-namespace-qualification.adoc +720 -0
  54. data/docs/_guides/xml-namespaces.adoc +2613 -0
  55. data/docs/_guides/xml_mappings/01_introduction.adoc +65 -0
  56. data/docs/_guides/xml_mappings/02_core_concepts.adoc +177 -0
  57. data/docs/_guides/xml_mappings/03_architecture.adoc +205 -0
  58. data/docs/_guides/xml_mappings/04_xml_namespace_class.adoc +1754 -0
  59. data/docs/_guides/xml_mappings/05_common_patterns.adoc +1803 -0
  60. data/docs/_guides/xml_mappings/06_migration_guide.adoc +523 -0
  61. data/docs/_guides/xml_mappings/07_best_practices.adoc +959 -0
  62. data/docs/_guides/xml_mappings/08_troubleshooting.adoc +934 -0
  63. data/docs/_migrations/0-1-0-migrate-from-shale.adoc +304 -0
  64. data/docs/_migrations/0-8-0-namespace-restructuring.adoc +1572 -0
  65. data/docs/_migrations/0-8-0-xsd-features.adoc +729 -0
  66. data/docs/_migrations/index.adoc +18 -0
  67. data/docs/_migrations/xsd-type-migration.adoc +1294 -0
  68. data/docs/_pages/attributes.adoc +1156 -0
  69. data/docs/_pages/breaking-changes.adoc +154 -0
  70. data/docs/_pages/collections.adoc +1664 -0
  71. data/docs/_pages/comparison-with-shale.adoc +139 -0
  72. data/docs/_pages/configuration.adoc +306 -0
  73. data/docs/_pages/consolidation-mapping.adoc +252 -0
  74. data/docs/_pages/importable_models.adoc +591 -0
  75. data/docs/_pages/index.adoc +46 -0
  76. data/docs/_pages/installation.adoc +35 -0
  77. data/docs/_pages/models.adoc +332 -0
  78. data/docs/_pages/quick-start.adoc +124 -0
  79. data/docs/_pages/serialization_adapters.adoc +319 -0
  80. data/docs/_pages/troubleshooting.adoc +104 -0
  81. data/docs/_pages/validation.adoc +171 -0
  82. data/docs/_pages/value_types.adoc +1514 -0
  83. data/docs/_pages/xml-conformance.adoc +143 -0
  84. data/docs/_references/architecture.adoc +189 -0
  85. data/docs/{custom_adapters.adoc → _references/custom_adapters.adoc} +6 -1
  86. data/docs/_references/custom_registers.adoc +1026 -0
  87. data/docs/_references/data-modeling-in-a-nutshell.adoc +207 -0
  88. data/docs/_references/format-independent-features.adoc +713 -0
  89. data/docs/_references/index.adoc +47 -0
  90. data/docs/_references/instance-serialization.adoc +120 -0
  91. data/docs/_references/lutaml-namespace-planning.md +120 -0
  92. data/docs/_references/parent-root-context.adoc +122 -0
  93. data/docs/_references/reference_type.adoc +302 -0
  94. data/docs/_references/serialization-model-mappings.adoc +102 -0
  95. data/docs/_references/three-phase-namespace-architecture.adoc +470 -0
  96. data/docs/_references/xml-w3c-namespace-qualification.adoc +66 -0
  97. data/docs/_references/xsd-generation-with-namespace-support.adoc +449 -0
  98. data/docs/_references/xsd-schema-parsing.adoc +1260 -0
  99. data/docs/_references/xsd-type-architecture.adoc +534 -0
  100. data/docs/_tutorials/basic-model-definition.adoc +157 -0
  101. data/docs/_tutorials/custom-types-tutorial.adoc +258 -0
  102. data/docs/_tutorials/first-json-serialization.adoc +192 -0
  103. data/docs/_tutorials/first-xml-serialization.adoc +223 -0
  104. data/docs/_tutorials/index.adoc +60 -0
  105. data/docs/_tutorials/lutaml-xml-architecture.adoc +1354 -0
  106. data/docs/_tutorials/polymorphic-models-tutorial.adoc +253 -0
  107. data/docs/_tutorials/schema-compiler-module-namespaces.adoc +497 -0
  108. data/docs/_tutorials/validation-basics.adoc +232 -0
  109. data/docs/_tutorials/working-with-collections.adoc +201 -0
  110. data/docs/_tutorials/xml-element-attribute-namespace-guide.adoc +279 -0
  111. data/docs/_tutorials/xml-namespaces-basics.adoc +315 -0
  112. data/docs/_tutorials/xml-schema-primer-style-guide.adoc +1394 -0
  113. data/docs/architecture.md +424 -0
  114. data/docs/bugreports/BUGREPORT_element_order_render_empty.md +99 -0
  115. data/docs/cli_compare.adoc +249 -0
  116. data/docs/collection_validation.adoc +366 -0
  117. data/docs/index.adoc +108 -0
  118. data/docs/key_value_data_model.adoc +1229 -0
  119. data/docs/model_transforms.adoc +769 -0
  120. data/docs/namespace-management.adoc +1051 -0
  121. data/docs/xml-schema-qualification.md +171 -0
  122. data/docs/yamls_sequence.adoc +335 -0
  123. data/lib/lutaml/{model/hash_adapter → hash_format/adapter}/document.rb +3 -4
  124. data/lib/lutaml/hash_format/adapter/mapping.rb +19 -0
  125. data/lib/lutaml/hash_format/adapter/mapping_rule.rb +9 -0
  126. data/lib/lutaml/{model/hash_adapter → hash_format/adapter}/standard_adapter.rb +3 -3
  127. data/lib/lutaml/hash_format/adapter/transform.rb +9 -0
  128. data/lib/lutaml/hash_format/adapter.rb +13 -0
  129. data/lib/lutaml/hash_format/type/serializers.rb +24 -0
  130. data/lib/lutaml/hash_format.rb +29 -0
  131. data/lib/lutaml/{model/json → json/adapter}/document.rb +3 -3
  132. data/lib/lutaml/json/adapter/mapping.rb +19 -0
  133. data/lib/lutaml/json/adapter/mapping_rule.rb +9 -0
  134. data/lib/lutaml/json/adapter/multi_json_adapter.rb +38 -0
  135. data/lib/lutaml/json/adapter/oj_adapter.rb +38 -0
  136. data/lib/lutaml/json/adapter/standard_adapter.rb +36 -0
  137. data/lib/lutaml/json/adapter/transform.rb +9 -0
  138. data/lib/lutaml/json/adapter.rb +20 -0
  139. data/lib/lutaml/json/schema/json_schema.rb +62 -0
  140. data/lib/lutaml/json/schema.rb +9 -0
  141. data/lib/lutaml/json/type/serializers.rb +72 -0
  142. data/lib/lutaml/json.rb +62 -0
  143. data/lib/lutaml/{model/jsonl → jsonl/adapter}/document.rb +2 -2
  144. data/lib/lutaml/jsonl/adapter/mapping.rb +19 -0
  145. data/lib/lutaml/jsonl/adapter/mapping_rule.rb +9 -0
  146. data/lib/lutaml/{model/jsonl → jsonl/adapter}/standard_adapter.rb +5 -4
  147. data/lib/lutaml/jsonl/adapter/transform.rb +26 -0
  148. data/lib/lutaml/jsonl/adapter.rb +13 -0
  149. data/lib/lutaml/jsonl.rb +21 -0
  150. data/lib/lutaml/key_value/adapter/hash/document.rb +13 -0
  151. data/lib/lutaml/key_value/adapter/hash/mapping.rb +19 -0
  152. data/lib/lutaml/key_value/adapter/hash/mapping_rule.rb +9 -0
  153. data/lib/lutaml/key_value/adapter/hash/standard_adapter.rb +19 -0
  154. data/lib/lutaml/key_value/adapter/hash/transform.rb +10 -0
  155. data/lib/lutaml/key_value/adapter/hash.rb +15 -0
  156. data/lib/lutaml/key_value/adapter/json/document.rb +16 -0
  157. data/lib/lutaml/key_value/adapter/json/mapping.rb +24 -0
  158. data/lib/lutaml/key_value/adapter/json/mapping_rule.rb +14 -0
  159. data/lib/lutaml/key_value/adapter/json/multi_json_adapter.rb +43 -0
  160. data/lib/lutaml/key_value/adapter/json/oj_adapter.rb +43 -0
  161. data/lib/lutaml/key_value/adapter/json/standard_adapter.rb +41 -0
  162. data/lib/lutaml/key_value/adapter/json/transform.rb +14 -0
  163. data/lib/lutaml/key_value/adapter/json.rb +24 -0
  164. data/lib/lutaml/key_value/adapter/jsonl/document.rb +16 -0
  165. data/lib/lutaml/key_value/adapter/jsonl/mapping.rb +19 -0
  166. data/lib/lutaml/key_value/adapter/jsonl/mapping_rule.rb +9 -0
  167. data/lib/lutaml/key_value/adapter/jsonl/standard_adapter.rb +36 -0
  168. data/lib/lutaml/key_value/adapter/jsonl/transform.rb +26 -0
  169. data/lib/lutaml/key_value/adapter/jsonl.rb +17 -0
  170. data/lib/lutaml/key_value/adapter/toml/document.rb +13 -0
  171. data/lib/lutaml/key_value/adapter/toml/mapping.rb +28 -0
  172. data/lib/lutaml/key_value/adapter/toml/mapping_rule.rb +9 -0
  173. data/lib/lutaml/key_value/adapter/toml/toml_rb_adapter.rb +40 -0
  174. data/lib/lutaml/key_value/adapter/toml/tomlib_adapter.rb +46 -0
  175. data/lib/lutaml/key_value/adapter/toml/transform.rb +10 -0
  176. data/lib/lutaml/key_value/adapter/toml.rb +21 -0
  177. data/lib/lutaml/key_value/adapter/yaml/document.rb +12 -0
  178. data/lib/lutaml/key_value/adapter/yaml/mapping.rb +19 -0
  179. data/lib/lutaml/key_value/adapter/yaml/mapping_rule.rb +9 -0
  180. data/lib/lutaml/key_value/adapter/yaml/standard_adapter.rb +41 -0
  181. data/lib/lutaml/key_value/adapter/yaml/transform.rb +10 -0
  182. data/lib/lutaml/key_value/adapter/yaml.rb +17 -0
  183. data/lib/lutaml/key_value/adapter/yamls/document.rb +16 -0
  184. data/lib/lutaml/key_value/adapter/yamls/mapping.rb +19 -0
  185. data/lib/lutaml/key_value/adapter/yamls/mapping_rule.rb +9 -0
  186. data/lib/lutaml/key_value/adapter/yamls/standard_adapter.rb +37 -0
  187. data/lib/lutaml/key_value/adapter/yamls/transform.rb +26 -0
  188. data/lib/lutaml/key_value/adapter/yamls.rb +17 -0
  189. data/lib/lutaml/key_value/adapter.rb +14 -0
  190. data/lib/lutaml/key_value/data_model/element.rb +222 -0
  191. data/lib/lutaml/key_value/data_model.rb +14 -0
  192. data/lib/lutaml/{model/key_value_document.rb → key_value/document.rb} +2 -2
  193. data/lib/lutaml/{model/mapping/key_value_mapping.rb → key_value/mapping.rb} +81 -43
  194. data/lib/lutaml/{model/mapping/key_value_mapping_rule.rb → key_value/mapping_rule.rb} +9 -10
  195. data/lib/lutaml/{model/transform/key_value_transform.rb → key_value/transform.rb} +111 -65
  196. data/lib/lutaml/key_value/transformation/collection_serializer.rb +575 -0
  197. data/lib/lutaml/key_value/transformation/rule_compiler.rb +294 -0
  198. data/lib/lutaml/key_value/transformation/value_serializer.rb +268 -0
  199. data/lib/lutaml/key_value/transformation.rb +1071 -0
  200. data/lib/lutaml/key_value/transformation_builder.rb +30 -0
  201. data/lib/lutaml/key_value.rb +24 -0
  202. data/lib/lutaml/model/adapter_resolver.rb +410 -0
  203. data/lib/lutaml/model/adapter_scope.rb +64 -0
  204. data/lib/lutaml/model/attribute.rb +515 -121
  205. data/lib/lutaml/model/attribute_validator.rb +288 -0
  206. data/lib/lutaml/model/cached_type_resolver/concurrent_map_cache.rb +46 -0
  207. data/lib/lutaml/model/cached_type_resolver/mutex_hash_cache.rb +51 -0
  208. data/lib/lutaml/model/cached_type_resolver.rb +144 -0
  209. data/lib/lutaml/model/choice.rb +230 -13
  210. data/lib/lutaml/model/cli.rb +75 -121
  211. data/lib/lutaml/model/collection.rb +510 -43
  212. data/lib/lutaml/model/collection_handler.rb +106 -0
  213. data/lib/lutaml/model/comparable_model.rb +11 -3
  214. data/lib/lutaml/model/comparable_nil.rb +0 -2
  215. data/lib/lutaml/model/compiled_rule.rb +208 -0
  216. data/lib/lutaml/model/config.rb +111 -80
  217. data/lib/lutaml/model/configuration.rb +91 -0
  218. data/lib/lutaml/model/consolidation/attribute_grouper.rb +44 -0
  219. data/lib/lutaml/model/consolidation/dispatcher.rb +45 -0
  220. data/lib/lutaml/model/consolidation/engine.rb +33 -0
  221. data/lib/lutaml/model/consolidation/pattern_chunker.rb +87 -0
  222. data/lib/lutaml/model/consolidation_map.rb +68 -0
  223. data/lib/lutaml/model/consolidation_rule/dispatch_block.rb +34 -0
  224. data/lib/lutaml/model/consolidation_rule/gather_rule.rb +17 -0
  225. data/lib/lutaml/model/consolidation_rule/pattern_content_rule.rb +15 -0
  226. data/lib/lutaml/model/consolidation_rule/pattern_element_rule.rb +17 -0
  227. data/lib/lutaml/model/consolidation_rule.rb +27 -0
  228. data/lib/lutaml/model/constants.rb +5 -3
  229. data/lib/lutaml/model/context_registry.rb +208 -0
  230. data/lib/lutaml/model/error/element_count_out_of_range_error.rb +13 -7
  231. data/lib/lutaml/model/error/format_adapter_not_specified_error.rb +25 -0
  232. data/lib/lutaml/model/error/invalid_attribute_type_error.rb +98 -0
  233. data/lib/lutaml/model/error/invalid_format_error.rb +11 -0
  234. data/lib/lutaml/model/error/liquid_class_not_found_error.rb +9 -0
  235. data/lib/lutaml/model/error/mapping_already_exists_error.rb +6 -0
  236. data/lib/lutaml/model/error/mapping_attribute_missing_error.rb +6 -0
  237. data/lib/lutaml/model/error/mapping_attribute_type_error.rb +6 -0
  238. data/lib/lutaml/model/error/mixed_content_collection_error.rb +17 -0
  239. data/lib/lutaml/model/error/no_attributes_defined_liquid_error.rb +9 -0
  240. data/lib/lutaml/model/error/no_mapping_found_error.rb +9 -0
  241. data/lib/lutaml/model/error/required_attribute_missing_error.rb +9 -0
  242. data/lib/lutaml/model/error/reverse_transform_block_not_defined_error.rb +6 -0
  243. data/lib/lutaml/model/error/reverse_transformation_declaration_error.rb +6 -0
  244. data/lib/lutaml/model/error/sorting_configuration_conflict_error.rb +9 -0
  245. data/lib/lutaml/model/error/transform_block_not_defined_error.rb +6 -0
  246. data/lib/lutaml/model/error/type.rb +17 -0
  247. data/lib/lutaml/model/error/undefined_attribute_error.rb +9 -0
  248. data/lib/lutaml/model/error/unknown_adapter_type_error.rb +82 -3
  249. data/lib/lutaml/model/error/unknown_type_error.rb +25 -2
  250. data/lib/lutaml/model/error/unresolvable_type_error.rb +27 -0
  251. data/lib/lutaml/model/error.rb +2 -33
  252. data/lib/lutaml/model/errors.rb +4 -2
  253. data/lib/lutaml/model/finalization_cache.rb +51 -0
  254. data/lib/lutaml/model/format_registry.rb +170 -9
  255. data/lib/lutaml/model/global_context.rb +446 -0
  256. data/lib/lutaml/model/global_register.rb +106 -5
  257. data/lib/lutaml/model/hash.rb +15 -0
  258. data/lib/lutaml/model/import_registry.rb +250 -0
  259. data/lib/lutaml/model/instrumentation.rb +304 -0
  260. data/lib/lutaml/model/json.rb +17 -13
  261. data/lib/lutaml/model/jsonl.rb +7 -13
  262. data/lib/lutaml/model/liquefiable.rb +100 -12
  263. data/lib/lutaml/model/liquid/mapping.rb +30 -0
  264. data/lib/lutaml/model/liquid.rb +9 -0
  265. data/lib/lutaml/model/mapping/listener.rb +124 -0
  266. data/lib/lutaml/model/mapping/mapping.rb +99 -1
  267. data/lib/lutaml/model/mapping/mapping_rule.rb +172 -17
  268. data/lib/lutaml/model/mapping/model_mapping.rb +133 -0
  269. data/lib/lutaml/model/mapping/model_mapping_rule.rb +57 -0
  270. data/lib/lutaml/model/mapping_hash.rb +3 -1
  271. data/lib/lutaml/model/model_transformer.rb +101 -0
  272. data/lib/lutaml/model/one_entry_cache.rb +57 -0
  273. data/lib/lutaml/model/organization.rb +29 -0
  274. data/lib/lutaml/model/register/model_tree_importer.rb +88 -0
  275. data/lib/lutaml/model/register/namespace_binding.rb +92 -0
  276. data/lib/lutaml/model/register.rb +500 -35
  277. data/lib/lutaml/model/registrable.rb +2 -0
  278. data/lib/lutaml/model/render_policy.rb +154 -0
  279. data/lib/lutaml/model/runtime_compatibility.rb +95 -0
  280. data/lib/lutaml/model/schema/base_schema.rb +1 -3
  281. data/lib/lutaml/model/schema/decorators/attribute.rb +3 -1
  282. data/lib/lutaml/model/schema/decorators/choices.rb +0 -2
  283. data/lib/lutaml/model/schema/decorators/class_definition.rb +4 -5
  284. data/lib/lutaml/model/schema/decorators/definition_collection.rb +7 -7
  285. data/lib/lutaml/model/schema/decorators.rb +15 -0
  286. data/lib/lutaml/model/schema/generator/definition.rb +4 -3
  287. data/lib/lutaml/model/schema/generator/definitions_collection.rb +4 -3
  288. data/lib/lutaml/model/schema/generator/properties_collection.rb +7 -5
  289. data/lib/lutaml/model/schema/generator/property.rb +5 -1
  290. data/lib/lutaml/model/schema/generator.rb +15 -0
  291. data/lib/lutaml/model/schema/helpers.rb +11 -0
  292. data/lib/lutaml/model/schema/json_schema.rb +9 -53
  293. data/lib/lutaml/model/schema/renderer.rb +19 -17
  294. data/lib/lutaml/model/schema/schema_builder/nokogiri.rb +41 -0
  295. data/lib/lutaml/model/schema/schema_builder/oga.rb +92 -0
  296. data/lib/lutaml/model/schema/shared_methods.rb +2 -2
  297. data/lib/lutaml/model/schema/xml_compiler/attribute.rb +33 -12
  298. data/lib/lutaml/model/schema/xml_compiler/attribute_group.rb +3 -1
  299. data/lib/lutaml/model/schema/xml_compiler/choice.rb +4 -2
  300. data/lib/lutaml/model/schema/xml_compiler/complex_type.rb +73 -36
  301. data/lib/lutaml/model/schema/xml_compiler/element.rb +18 -1
  302. data/lib/lutaml/model/schema/xml_compiler/group.rb +20 -4
  303. data/lib/lutaml/model/schema/xml_compiler/registry_generator.rb +127 -0
  304. data/lib/lutaml/model/schema/xml_compiler/restriction.rb +5 -2
  305. data/lib/lutaml/model/schema/xml_compiler/sequence.rb +6 -2
  306. data/lib/lutaml/model/schema/xml_compiler/simple_content.rb +7 -3
  307. data/lib/lutaml/model/schema/xml_compiler/simple_type.rb +127 -51
  308. data/lib/lutaml/model/schema/xml_compiler/xml_namespace_class.rb +110 -0
  309. data/lib/lutaml/model/schema/xml_compiler.rb +256 -82
  310. data/lib/lutaml/model/schema/yaml_schema.rb +10 -50
  311. data/lib/lutaml/model/schema.rb +49 -14
  312. data/lib/lutaml/model/schema_location.rb +12 -60
  313. data/lib/lutaml/model/sequence.rb +102 -30
  314. data/lib/lutaml/model/serializable.rb +1 -3
  315. data/lib/lutaml/model/serialization_adapter.rb +2 -0
  316. data/lib/lutaml/model/serialize/attribute_definition.rb +229 -0
  317. data/lib/lutaml/model/serialize/builder.rb +169 -0
  318. data/lib/lutaml/model/serialize/enum_handling.rb +124 -0
  319. data/lib/lutaml/model/serialize/format_conversion.rb +337 -0
  320. data/lib/lutaml/model/serialize/initialization.rb +308 -0
  321. data/lib/lutaml/model/serialize/model_import.rb +357 -0
  322. data/lib/lutaml/model/serialize/transformation_builder.rb +127 -0
  323. data/lib/lutaml/model/serialize/value_mapping.rb +200 -0
  324. data/lib/lutaml/model/serialize.rb +175 -578
  325. data/lib/lutaml/model/services/base.rb +2 -2
  326. data/lib/lutaml/model/services/default_value_resolver.rb +60 -0
  327. data/lib/lutaml/model/services/logger.rb +10 -7
  328. data/lib/lutaml/model/services/rule_value_extractor.rb +22 -36
  329. data/lib/lutaml/model/services/transformer.rb +50 -9
  330. data/lib/lutaml/model/services/type/validator/string.rb +3 -2
  331. data/lib/lutaml/model/services/type/validator/symbol.rb +30 -0
  332. data/lib/lutaml/model/services/type/validator.rb +5 -2
  333. data/lib/lutaml/model/services/type.rb +9 -0
  334. data/lib/lutaml/model/services/validator.rb +1 -3
  335. data/lib/lutaml/model/services.rb +12 -5
  336. data/lib/lutaml/model/store.rb +59 -0
  337. data/lib/lutaml/model/toml.rb +24 -18
  338. data/lib/lutaml/model/transform/xml_transform.rb +4 -227
  339. data/lib/lutaml/model/transform.rb +49 -17
  340. data/lib/lutaml/model/transformation.rb +84 -0
  341. data/lib/lutaml/model/transformation_builder.rb +55 -0
  342. data/lib/lutaml/model/transformation_registry.rb +314 -0
  343. data/lib/lutaml/model/type/base64_binary.rb +58 -0
  344. data/lib/lutaml/model/type/boolean.rb +9 -16
  345. data/lib/lutaml/model/type/date.rb +49 -9
  346. data/lib/lutaml/model/type/date_time.rb +30 -18
  347. data/lib/lutaml/model/type/decimal.rb +28 -9
  348. data/lib/lutaml/model/type/duration.rb +82 -0
  349. data/lib/lutaml/model/type/float.rb +12 -13
  350. data/lib/lutaml/model/type/hash.rb +10 -17
  351. data/lib/lutaml/model/type/hex_binary.rb +56 -0
  352. data/lib/lutaml/model/type/integer.rb +19 -1
  353. data/lib/lutaml/model/type/qname.rb +85 -0
  354. data/lib/lutaml/model/type/reference.rb +76 -0
  355. data/lib/lutaml/model/type/string.rb +18 -35
  356. data/lib/lutaml/model/type/symbol.rb +67 -0
  357. data/lib/lutaml/model/type/time.rb +19 -22
  358. data/lib/lutaml/model/type/time_without_date.rb +18 -18
  359. data/lib/lutaml/model/type/uninitialized_class_guard.rb +36 -0
  360. data/lib/lutaml/model/type/uri.rb +51 -0
  361. data/lib/lutaml/model/type/value.rb +52 -5
  362. data/lib/lutaml/model/type.rb +98 -13
  363. data/lib/lutaml/model/type_context.rb +279 -0
  364. data/lib/lutaml/model/type_registry.rb +165 -0
  365. data/lib/lutaml/model/type_resolver.rb +185 -0
  366. data/lib/lutaml/model/type_substitution.rb +117 -0
  367. data/lib/lutaml/model/uninitialized_class.rb +1 -1
  368. data/lib/lutaml/model/utils.rb +110 -9
  369. data/lib/lutaml/model/validation.rb +50 -7
  370. data/lib/lutaml/model/value_transformer.rb +25 -0
  371. data/lib/lutaml/model/version.rb +1 -1
  372. data/lib/lutaml/model/yaml.rb +7 -13
  373. data/lib/lutaml/model/yamls.rb +7 -13
  374. data/lib/lutaml/model.rb +229 -25
  375. data/lib/lutaml/{model/toml → toml/adapter}/document.rb +3 -4
  376. data/lib/lutaml/{model/toml → toml/adapter}/mapping.rb +7 -6
  377. data/lib/lutaml/toml/adapter/mapping_rule.rb +9 -0
  378. data/lib/lutaml/toml/adapter/toml_rb_adapter.rb +38 -0
  379. data/lib/lutaml/toml/adapter/tomlib_adapter.rb +54 -0
  380. data/lib/lutaml/toml/adapter/transform.rb +9 -0
  381. data/lib/lutaml/toml/adapter.rb +19 -0
  382. data/lib/lutaml/toml/type/serializers.rb +71 -0
  383. data/lib/lutaml/toml.rb +48 -0
  384. data/lib/lutaml/xml/adapter/adapter_helpers.rb +149 -0
  385. data/lib/lutaml/xml/adapter/base_adapter.rb +672 -0
  386. data/lib/lutaml/xml/adapter/namespace_data.rb +73 -0
  387. data/lib/lutaml/xml/adapter/nokogiri_adapter.rb +1115 -0
  388. data/lib/lutaml/xml/adapter/oga_adapter.rb +849 -0
  389. data/lib/lutaml/xml/adapter/ox_adapter.rb +891 -0
  390. data/lib/lutaml/xml/adapter/rexml_adapter.rb +869 -0
  391. data/lib/lutaml/xml/adapter/xml_serialization.rb +145 -0
  392. data/lib/lutaml/xml/adapter.rb +20 -0
  393. data/lib/lutaml/xml/adapter_element.rb +185 -0
  394. data/lib/lutaml/xml/adapter_loader.rb +53 -0
  395. data/lib/lutaml/xml/attribute_namespace_resolver.rb +139 -0
  396. data/lib/lutaml/xml/blank_namespace.rb +51 -0
  397. data/lib/lutaml/xml/blank_namespace_handler.rb +50 -0
  398. data/lib/lutaml/xml/builder/base.rb +215 -0
  399. data/lib/lutaml/xml/builder/nokogiri.rb +12 -0
  400. data/lib/lutaml/xml/builder/oga.rb +15 -0
  401. data/lib/lutaml/xml/builder/ox.rb +15 -0
  402. data/lib/lutaml/xml/builder/rexml.rb +15 -0
  403. data/lib/lutaml/xml/builder.rb +16 -0
  404. data/lib/lutaml/xml/configurable.rb +214 -0
  405. data/lib/lutaml/xml/data_model.rb +257 -0
  406. data/lib/lutaml/xml/decisions/decision.rb +103 -0
  407. data/lib/lutaml/xml/decisions/decision_context.rb +225 -0
  408. data/lib/lutaml/xml/decisions/decision_engine.rb +67 -0
  409. data/lib/lutaml/xml/decisions/decision_rule.rb +54 -0
  410. data/lib/lutaml/xml/decisions/element_prefix_resolver.rb +85 -0
  411. data/lib/lutaml/xml/decisions/rules/attribute_usage_rule.rb +37 -0
  412. data/lib/lutaml/xml/decisions/rules/default_preference_rule.rb +62 -0
  413. data/lib/lutaml/xml/decisions/rules/element_form_default_rule.rb +66 -0
  414. data/lib/lutaml/xml/decisions/rules/element_form_default_unqualified_rule.rb +73 -0
  415. data/lib/lutaml/xml/decisions/rules/element_form_option_rule.rb +83 -0
  416. data/lib/lutaml/xml/decisions/rules/explicit_option_rule.rb +57 -0
  417. data/lib/lutaml/xml/decisions/rules/format_preservation_rule.rb +74 -0
  418. data/lib/lutaml/xml/decisions/rules/hoisted_on_parent_rule.rb +60 -0
  419. data/lib/lutaml/xml/decisions/rules/inherit_from_parent_rule.rb +52 -0
  420. data/lib/lutaml/xml/decisions/rules/inherit_parent_prefix_rule.rb +69 -0
  421. data/lib/lutaml/xml/decisions/rules/namespace_scope_rule.rb +54 -0
  422. data/lib/lutaml/xml/decisions/rules/reuse_parent_prefix_rule.rb +78 -0
  423. data/lib/lutaml/xml/decisions/rules/used_prefix_rule.rb +70 -0
  424. data/lib/lutaml/xml/decisions/rules.rb +39 -0
  425. data/lib/lutaml/xml/decisions.rb +15 -0
  426. data/lib/lutaml/xml/declaration_handler.rb +217 -0
  427. data/lib/lutaml/xml/declaration_plan/attribute_node.rb +81 -0
  428. data/lib/lutaml/xml/declaration_plan/element_node.rb +101 -0
  429. data/lib/lutaml/xml/declaration_plan.rb +480 -0
  430. data/lib/lutaml/xml/declaration_plan_query.rb +105 -0
  431. data/lib/lutaml/xml/declaration_planner.rb +1849 -0
  432. data/lib/lutaml/xml/doctype_extractor.rb +51 -0
  433. data/lib/lutaml/xml/document.rb +380 -0
  434. data/lib/lutaml/xml/element.rb +93 -0
  435. data/lib/lutaml/xml/element_prefix_resolver.rb +50 -0
  436. data/lib/lutaml/xml/encoding_normalizer.rb +54 -0
  437. data/lib/lutaml/xml/error/invalid_namespace_error.rb +46 -0
  438. data/lib/lutaml/xml/error/invalid_xsd_type_error.rb +43 -0
  439. data/lib/lutaml/xml/error/namespace_mismatch_error.rb +53 -0
  440. data/lib/lutaml/xml/error/xml_configuration_error.rb +17 -0
  441. data/lib/lutaml/xml/error/xml_error.rb +21 -0
  442. data/lib/lutaml/xml/format_chooser.rb +214 -0
  443. data/lib/lutaml/xml/hoisting_algorithm.rb +234 -0
  444. data/lib/lutaml/xml/listener.rb +33 -0
  445. data/lib/lutaml/xml/mapping.rb +1470 -0
  446. data/lib/lutaml/xml/mapping_rule.rb +565 -0
  447. data/lib/lutaml/xml/model_transform.rb +944 -0
  448. data/lib/lutaml/xml/namespace.rb +435 -0
  449. data/lib/lutaml/xml/namespace_class_registry.rb +144 -0
  450. data/lib/lutaml/xml/namespace_collector.rb +611 -0
  451. data/lib/lutaml/xml/namespace_declaration.rb +202 -0
  452. data/lib/lutaml/xml/namespace_declaration_builder.rb +67 -0
  453. data/lib/lutaml/xml/namespace_declaration_data.rb +182 -0
  454. data/lib/lutaml/xml/namespace_inheritance_resolver.rb +142 -0
  455. data/lib/lutaml/xml/namespace_inheritance_strategy.rb +26 -0
  456. data/lib/lutaml/xml/namespace_needs.rb +213 -0
  457. data/lib/lutaml/xml/namespace_resolution_strategy.rb +230 -0
  458. data/lib/lutaml/xml/namespace_resolver.rb +219 -0
  459. data/lib/lutaml/xml/namespace_scope_config.rb +109 -0
  460. data/lib/lutaml/xml/namespace_type_resolver.rb +135 -0
  461. data/lib/lutaml/xml/namespace_usage.rb +121 -0
  462. data/lib/lutaml/xml/nokogiri/element.rb +34 -0
  463. data/lib/lutaml/xml/nokogiri.rb +10 -0
  464. data/lib/lutaml/xml/oga/element.rb +15 -0
  465. data/lib/lutaml/xml/oga.rb +10 -0
  466. data/lib/lutaml/xml/ox/element.rb +15 -0
  467. data/lib/lutaml/xml/ox.rb +10 -0
  468. data/lib/lutaml/xml/parsed_namespace_declaration.rb +129 -0
  469. data/lib/lutaml/xml/parsed_namespace_set.rb +149 -0
  470. data/lib/lutaml/xml/polymorphic_value_handler.rb +41 -0
  471. data/lib/lutaml/xml/qualified_inheritance_strategy.rb +27 -0
  472. data/lib/lutaml/xml/rexml/element.rb +15 -0
  473. data/lib/lutaml/xml/rexml.rb +10 -0
  474. data/lib/lutaml/xml/schema/builder/nokogiri.rb +41 -0
  475. data/lib/lutaml/xml/schema/builder/oga.rb +92 -0
  476. data/lib/lutaml/xml/schema/builder.rb +59 -0
  477. data/lib/lutaml/xml/schema/builtin_types.rb +112 -0
  478. data/lib/lutaml/{model → xml}/schema/relaxng_schema.rb +9 -4
  479. data/lib/lutaml/xml/schema/xsd/all.rb +31 -0
  480. data/lib/lutaml/xml/schema/xsd/annotation.rb +31 -0
  481. data/lib/lutaml/xml/schema/xsd/any.rb +33 -0
  482. data/lib/lutaml/xml/schema/xsd/any_attribute.rb +29 -0
  483. data/lib/lutaml/xml/schema/xsd/appinfo.rb +25 -0
  484. data/lib/lutaml/xml/schema/xsd/attribute.rb +78 -0
  485. data/lib/lutaml/xml/schema/xsd/attribute_group.rb +89 -0
  486. data/lib/lutaml/xml/schema/xsd/base.rb +267 -0
  487. data/lib/lutaml/xml/schema/xsd/choice.rb +68 -0
  488. data/lib/lutaml/xml/schema/xsd/complex_content.rb +39 -0
  489. data/lib/lutaml/xml/schema/xsd/complex_type.rb +157 -0
  490. data/lib/lutaml/xml/schema/xsd/documentation.rb +26 -0
  491. data/lib/lutaml/xml/schema/xsd/element.rb +117 -0
  492. data/lib/lutaml/xml/schema/xsd/enumeration.rb +25 -0
  493. data/lib/lutaml/xml/schema/xsd/errors/enhanced_error.rb +142 -0
  494. data/lib/lutaml/xml/schema/xsd/errors/error_context.rb +67 -0
  495. data/lib/lutaml/xml/schema/xsd/errors/message_builder.rb +103 -0
  496. data/lib/lutaml/xml/schema/xsd/errors/suggestion.rb +67 -0
  497. data/lib/lutaml/xml/schema/xsd/errors/troubleshooters/namespace_troubleshooter.rb +96 -0
  498. data/lib/lutaml/xml/schema/xsd/errors/troubleshooters/troubleshooting_handler.rb +70 -0
  499. data/lib/lutaml/xml/schema/xsd/errors.rb +148 -0
  500. data/lib/lutaml/xml/schema/xsd/extension_complex_content.rb +63 -0
  501. data/lib/lutaml/xml/schema/xsd/extension_simple_content.rb +48 -0
  502. data/lib/lutaml/xml/schema/xsd/field.rb +25 -0
  503. data/lib/lutaml/xml/schema/xsd/file_validation_result.rb +55 -0
  504. data/lib/lutaml/xml/schema/xsd/fraction_digits.rb +29 -0
  505. data/lib/lutaml/xml/schema/xsd/glob.rb +105 -0
  506. data/lib/lutaml/xml/schema/xsd/group.rb +79 -0
  507. data/lib/lutaml/xml/schema/xsd/import.rb +33 -0
  508. data/lib/lutaml/xml/schema/xsd/include.rb +31 -0
  509. data/lib/lutaml/xml/schema/xsd/key.rb +32 -0
  510. data/lib/lutaml/xml/schema/xsd/keyref.rb +33 -0
  511. data/lib/lutaml/xml/schema/xsd/length.rb +27 -0
  512. data/lib/lutaml/xml/schema/xsd/list.rb +28 -0
  513. data/lib/lutaml/xml/schema/xsd/max_exclusive.rb +25 -0
  514. data/lib/lutaml/xml/schema/xsd/max_inclusive.rb +23 -0
  515. data/lib/lutaml/xml/schema/xsd/max_length.rb +25 -0
  516. data/lib/lutaml/xml/schema/xsd/min_exclusive.rb +25 -0
  517. data/lib/lutaml/xml/schema/xsd/min_inclusive.rb +23 -0
  518. data/lib/lutaml/xml/schema/xsd/min_length.rb +25 -0
  519. data/lib/lutaml/xml/schema/xsd/namespace_mapping.rb +37 -0
  520. data/lib/lutaml/xml/schema/xsd/namespace_uri_remapping.rb +79 -0
  521. data/lib/lutaml/xml/schema/xsd/notation.rb +31 -0
  522. data/lib/lutaml/xml/schema/xsd/pattern.rb +25 -0
  523. data/lib/lutaml/xml/schema/xsd/redefine.rb +35 -0
  524. data/lib/lutaml/xml/schema/xsd/restriction_complex_content.rb +56 -0
  525. data/lib/lutaml/xml/schema/xsd/restriction_simple_content.rb +84 -0
  526. data/lib/lutaml/xml/schema/xsd/restriction_simple_type.rb +64 -0
  527. data/lib/lutaml/xml/schema/xsd/schema.rb +373 -0
  528. data/lib/lutaml/xml/schema/xsd/schema_file_validation_results.rb +55 -0
  529. data/lib/lutaml/xml/schema/xsd/schema_location_mapping.rb +74 -0
  530. data/lib/lutaml/xml/schema/xsd/schema_name_resolver.rb +32 -0
  531. data/lib/lutaml/xml/schema/xsd/schema_path.rb +196 -0
  532. data/lib/lutaml/xml/schema/xsd/schema_validator.rb +256 -0
  533. data/lib/lutaml/xml/schema/xsd/selector.rb +27 -0
  534. data/lib/lutaml/xml/schema/xsd/sequence.rb +68 -0
  535. data/lib/lutaml/xml/schema/xsd/serialized_schema.rb +185 -0
  536. data/lib/lutaml/xml/schema/xsd/simple_content.rb +61 -0
  537. data/lib/lutaml/xml/schema/xsd/simple_type.rb +37 -0
  538. data/lib/lutaml/xml/schema/xsd/total_digits.rb +29 -0
  539. data/lib/lutaml/xml/schema/xsd/type_index_entry.rb +40 -0
  540. data/lib/lutaml/xml/schema/xsd/type_resolution_result.rb +112 -0
  541. data/lib/lutaml/xml/schema/xsd/union.rb +30 -0
  542. data/lib/lutaml/xml/schema/xsd/unique.rb +31 -0
  543. data/lib/lutaml/xml/schema/xsd/validation_error.rb +48 -0
  544. data/lib/lutaml/xml/schema/xsd/validation_result.rb +86 -0
  545. data/lib/lutaml/xml/schema/xsd/version.rb +11 -0
  546. data/lib/lutaml/xml/schema/xsd/white_space.rb +27 -0
  547. data/lib/lutaml/xml/schema/xsd.rb +165 -0
  548. data/lib/lutaml/xml/schema/xsd_namespace.rb +29 -0
  549. data/lib/lutaml/xml/schema/xsd_schema.rb +536 -0
  550. data/lib/lutaml/xml/schema.rb +13 -0
  551. data/lib/lutaml/xml/schema_location.rb +155 -0
  552. data/lib/lutaml/xml/serialization/collection_ext.rb +61 -0
  553. data/lib/lutaml/xml/serialization/format_conversion.rb +402 -0
  554. data/lib/lutaml/xml/serialization/instance_methods.rb +303 -0
  555. data/lib/lutaml/xml/serialization/model_import_ext.rb +40 -0
  556. data/lib/lutaml/xml/serialization.rb +15 -0
  557. data/lib/lutaml/xml/shared_dsl.rb +119 -0
  558. data/lib/lutaml/xml/transform.rb +6 -0
  559. data/lib/lutaml/xml/transformation/custom_method_wrapper.rb +262 -0
  560. data/lib/lutaml/xml/transformation/element_builder.rb +586 -0
  561. data/lib/lutaml/xml/transformation/ordered_applier.rb +329 -0
  562. data/lib/lutaml/xml/transformation/rule_applier.rb +379 -0
  563. data/lib/lutaml/xml/transformation/rule_compiler.rb +543 -0
  564. data/lib/lutaml/xml/transformation/skip_logic.rb +70 -0
  565. data/lib/lutaml/xml/transformation/value_serializer.rb +139 -0
  566. data/lib/lutaml/xml/transformation.rb +340 -0
  567. data/lib/lutaml/xml/transformation_builder.rb +28 -0
  568. data/lib/lutaml/xml/transformation_support.rb +14 -0
  569. data/lib/lutaml/xml/type/configurable.rb +157 -0
  570. data/lib/lutaml/xml/type/serializers.rb +98 -0
  571. data/lib/lutaml/xml/type/value_xml_mapping.rb +94 -0
  572. data/lib/lutaml/xml/type_namespace/collector.rb +101 -0
  573. data/lib/lutaml/xml/type_namespace/declaration.rb +61 -0
  574. data/lib/lutaml/xml/type_namespace/planner.rb +121 -0
  575. data/lib/lutaml/xml/type_namespace/reference.rb +71 -0
  576. data/lib/lutaml/xml/type_namespace/resolver.rb +43 -0
  577. data/lib/lutaml/xml/type_namespace.rb +13 -0
  578. data/lib/lutaml/xml/type_namespace_resolver.rb +76 -0
  579. data/lib/lutaml/xml/unqualified_inheritance_strategy.rb +34 -0
  580. data/lib/lutaml/xml/w3c/registration.rb +66 -0
  581. data/lib/lutaml/xml/w3c.rb +398 -0
  582. data/lib/lutaml/xml/xml_attribute.rb +38 -0
  583. data/lib/lutaml/xml/xml_element.rb +447 -0
  584. data/lib/lutaml/xml/xml_namespace.rb +72 -0
  585. data/lib/lutaml/xml.rb +294 -0
  586. data/lib/lutaml/{model/yaml → yaml/adapter}/document.rb +3 -3
  587. data/lib/lutaml/yaml/adapter/mapping.rb +19 -0
  588. data/lib/lutaml/yaml/adapter/mapping_rule.rb +9 -0
  589. data/lib/lutaml/yaml/adapter/standard_adapter.rb +39 -0
  590. data/lib/lutaml/yaml/adapter/transform.rb +9 -0
  591. data/lib/lutaml/yaml/adapter.rb +13 -0
  592. data/lib/lutaml/yaml/schema/yaml_schema.rb +65 -0
  593. data/lib/lutaml/yaml/schema.rb +9 -0
  594. data/lib/lutaml/yaml/type/serializers.rb +60 -0
  595. data/lib/lutaml/yaml.rb +30 -0
  596. data/lib/lutaml/{model/yamls → yamls/adapter}/document.rb +2 -2
  597. data/lib/lutaml/yamls/adapter/mapping.rb +26 -0
  598. data/lib/lutaml/yamls/adapter/mapping_rule.rb +9 -0
  599. data/lib/lutaml/yamls/adapter/standard_adapter.rb +56 -0
  600. data/lib/lutaml/yamls/adapter/transform.rb +124 -0
  601. data/lib/lutaml/yamls/adapter/yamls_sequence.rb +20 -0
  602. data/lib/lutaml/yamls/adapter/yamls_sequence_rule.rb +48 -0
  603. data/lib/lutaml/yamls/adapter.rb +15 -0
  604. data/lib/lutaml/yamls.rb +21 -0
  605. data/lib/tasks/benchmark_runner.rb +161 -0
  606. data/lib/tasks/memory_profile.rb +176 -0
  607. data/lib/tasks/performance.rake +75 -0
  608. data/lib/tasks/performance_benchmark.rb +499 -0
  609. data/lib/tasks/performance_comparator.rb +114 -0
  610. data/lib/tasks/performance_helpers.rb +149 -0
  611. data/lib/tasks/xml_compiler_benchmark.rb +226 -0
  612. data/lib/tasks/xml_optimization_benchmark.rb +178 -0
  613. data/lutaml-model.gemspec +11 -1
  614. data/reference-docs/XML Entity Definitions for Characters (3rd Edition).html +595 -0
  615. data/scripts-xmi-profile/profile_xmi.rb +192 -0
  616. data/scripts-xmi-profile/profile_xmi_simple.rb +210 -0
  617. data/spec/address_person_spec.rb +436 -0
  618. data/spec/address_spec.rb +20 -18
  619. data/spec/ceramic_spec.rb +25 -7
  620. data/spec/fixtures/address.rb +2 -2
  621. data/spec/fixtures/ceramic.rb +6 -2
  622. data/spec/fixtures/geolexica_v2_concept.rb +136 -0
  623. data/spec/fixtures/geolexica_v2_sample.yaml +36 -0
  624. data/spec/fixtures/geolexica_v2_sample2.yaml +38 -0
  625. data/spec/fixtures/person.rb +14 -13
  626. data/spec/fixtures/sample_model.rb +3 -3
  627. data/spec/fixtures/vase.rb +3 -3
  628. data/spec/fixtures/xml/address_example_260.xsd +8 -4
  629. data/spec/fixtures/xml/examples/nested_categories.xml +45 -51
  630. data/spec/fixtures/xml/examples/valid_catalog.xml +27 -41
  631. data/spec/fixtures/xml/math_document_schema.xsd +7 -5
  632. data/spec/fixtures/xml/product_catalog.xsd +19 -138
  633. data/spec/fixtures/xml/schema/xsd/build_test_package.rb +19 -0
  634. data/spec/fixtures/xml/schema/xsd/citygml/2.0/cityGMLBase.xsd +339 -0
  635. data/spec/fixtures/xml/schema/xsd/citygml/appearance/2.0/appearance.xsd +332 -0
  636. data/spec/fixtures/xml/schema/xsd/citygml/bridge/2.0/bridge.xsd +578 -0
  637. data/spec/fixtures/xml/schema/xsd/citygml/building/2.0/building.xsd +535 -0
  638. data/spec/fixtures/xml/schema/xsd/citygml/cityfurniture/2.0/cityFurniture.xsd +57 -0
  639. data/spec/fixtures/xml/schema/xsd/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd +84 -0
  640. data/spec/fixtures/xml/schema/xsd/citygml/examples/2.0/ade/noise-ade/CityGML-NoiseADE.xsd +174 -0
  641. data/spec/fixtures/xml/schema/xsd/citygml/examples/2.0/ade/robotics-ade/stdOp.xsd +46 -0
  642. data/spec/fixtures/xml/schema/xsd/citygml/examples/2.0/ade/robotics-ade/unr.xsd +46 -0
  643. data/spec/fixtures/xml/schema/xsd/citygml/generics/2.0/generics.xsd +184 -0
  644. data/spec/fixtures/xml/schema/xsd/citygml/landuse/2.0/landUse.xsd +50 -0
  645. data/spec/fixtures/xml/schema/xsd/citygml/profiles/base/2.0/CityGML.xsd +30 -0
  646. data/spec/fixtures/xml/schema/xsd/citygml/relief/2.0/relief.xsd +186 -0
  647. data/spec/fixtures/xml/schema/xsd/citygml/texturedsurface/2.0/texturedSurface.xsd +157 -0
  648. data/spec/fixtures/xml/schema/xsd/citygml/transportation/2.0/transportation.xsd +224 -0
  649. data/spec/fixtures/xml/schema/xsd/citygml/tunnel/2.0/tunnel.xsd +530 -0
  650. data/spec/fixtures/xml/schema/xsd/citygml/vegetation/2.0/vegetation.xsd +108 -0
  651. data/spec/fixtures/xml/schema/xsd/citygml/waterbody/2.0/waterBody.xsd +171 -0
  652. data/spec/fixtures/xml/schema/xsd/citygml/xAL/xAL.xsd +1680 -0
  653. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/basicTypes.xsd +262 -0
  654. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/coordinateOperations.xsd +519 -0
  655. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/coordinateReferenceSystems.xsd +367 -0
  656. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/coordinateSystems.xsd +291 -0
  657. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/coverage.xsd +287 -0
  658. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/datums.xsd +281 -0
  659. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/defaultStyle.xsd +447 -0
  660. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/deprecatedTypes.xsd +1128 -0
  661. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/dictionary.xsd +84 -0
  662. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/direction.xsd +78 -0
  663. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/dynamicFeature.xsd +103 -0
  664. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/feature.xsd +88 -0
  665. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/geometryAggregates.xsd +191 -0
  666. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/geometryBasic0d1d.xsd +271 -0
  667. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/geometryBasic2d.xsd +118 -0
  668. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/geometryComplexes.xsd +89 -0
  669. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/geometryPrimitives.xsd +841 -0
  670. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/gml.xsd +15 -0
  671. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/gmlBase.xsd +179 -0
  672. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/grids.xsd +58 -0
  673. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/measures.xsd +63 -0
  674. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/observation.xsd +90 -0
  675. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/referenceSystems.xsd +64 -0
  676. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/temporal.xsd +263 -0
  677. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/temporalReferenceSystems.xsd +183 -0
  678. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/temporalTopology.xsd +113 -0
  679. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/topology.xsd +380 -0
  680. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/units.xsd +156 -0
  681. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/gml/3.2.1/valueObjects.xsd +199 -0
  682. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gco/basicTypes.xsd +429 -0
  683. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gco/gco.xsd +12 -0
  684. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gco/gcoBase.xsd +61 -0
  685. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/applicationSchema.xsd +42 -0
  686. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/citation.xsd +275 -0
  687. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/constraints.xsd +106 -0
  688. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/content.xsd +188 -0
  689. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/dataQuality.xsd +554 -0
  690. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/distribution.xsd +202 -0
  691. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/extent.xsd +205 -0
  692. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/freeText.xsd +122 -0
  693. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/gmd.xsd +12 -0
  694. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/identification.xsd +348 -0
  695. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/maintenance.xsd +86 -0
  696. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/metadataApplication.xsd +175 -0
  697. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/metadataEntity.xsd +70 -0
  698. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/metadataExtension.xsd +99 -0
  699. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/portrayalCatalogue.xsd +36 -0
  700. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/referenceSystem.xsd +100 -0
  701. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmd/spatialRepresentation.xsd +237 -0
  702. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/catalogues.xsd +112 -0
  703. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/codelistItem.xsd +168 -0
  704. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/crsItem.xsd +1030 -0
  705. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/extendedTypes.xsd +75 -0
  706. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/gmx.xsd +2 -0
  707. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/gmxUsage.xsd +127 -0
  708. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gmx/uomItem.xsd +162 -0
  709. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gsr/gsr.xsd +12 -0
  710. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gsr/spatialReferencing.xsd +24 -0
  711. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gss/geometry.xsd +35 -0
  712. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gss/gss.xsd +12 -0
  713. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gts/gts.xsd +12 -0
  714. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/iso/19139/20070417/gts/temporalObjects.xsd +34 -0
  715. data/spec/fixtures/xml/schema/xsd/codesynthesis-gml-3.2.1/xlink/1.0.0/xlinks.xsd +122 -0
  716. data/spec/fixtures/xml/schema/xsd/i-ur/urbanFunction.xsd +2772 -0
  717. data/spec/fixtures/xml/schema/xsd/i-ur/urbanObject.xsd +3344 -0
  718. data/spec/fixtures/xml/schema/xsd/import-without-location.xsd +9 -0
  719. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gco/1.2/baseTypes.xsd +775 -0
  720. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gco/1.2/gco.xsd +17 -0
  721. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gco/1.2.0/baseTypes.xsd +775 -0
  722. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gco/1.2.0/gco.xsd +17 -0
  723. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gcx/1.2/extendedTypes.xsd +151 -0
  724. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gcx/1.2/gcx.xsd +16 -0
  725. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gcx/1.2.0/extendedTypes.xsd +151 -0
  726. data/spec/fixtures/xml/schema/xsd/isotc211/19103/-/gcx/1.2.0/gcx.xsd +16 -0
  727. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/coordinateGeometry.xsd +1078 -0
  728. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/geometricAggregates.xsd +141 -0
  729. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/geometricComplex.xsd +177 -0
  730. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/geometricPrimative.xsd +526 -0
  731. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/geometry.xsd +9 -0
  732. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/geometryRoot.xsd +59 -0
  733. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/gss.xsd +26 -0
  734. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/topoComplex.xsd +33 -0
  735. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/topoPrimative.xsd +432 -0
  736. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/topoRoot.xsd +9 -0
  737. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/1.0.0/topology.xsd +15 -0
  738. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/coordinates.xsd +15 -0
  739. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/curves.xsd +22 -0
  740. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/geometry.xsd +41 -0
  741. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/gss.xsd +21 -0
  742. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/simplicialGeometry.xsd +63 -0
  743. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/solids.xsd +21 -0
  744. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/surfaces.xsd +15 -0
  745. data/spec/fixtures/xml/schema/xsd/isotc211/19107/-/gss/2.0.0/topology.xsd +21 -0
  746. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.1.0/abstract.xsd +47 -0
  747. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.1.0/fcc.xsd +12 -0
  748. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.2/abstract.xsd +45 -0
  749. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.2/fcc.xsd +11 -0
  750. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.2.0/abstract.xsd +45 -0
  751. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/fcc/2.2.0/fcc.xsd +11 -0
  752. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/1.0/gfc.xsd +497 -0
  753. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.1.0/featureCatalogue.xsd +673 -0
  754. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.1.0/gfc.xsd +19 -0
  755. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.2/featureCatalogue.xsd +798 -0
  756. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.2/gfc.xsd +19 -0
  757. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.2.0/featureCatalogue.xsd +798 -0
  758. data/spec/fixtures/xml/schema/xsd/isotc211/19110/-/gfc/2.2.0/gfc.xsd +19 -0
  759. data/spec/fixtures/xml/schema/xsd/isotc211/19110/fcc/1.0/abstract.xsd +49 -0
  760. data/spec/fixtures/xml/schema/xsd/isotc211/19110/fcc/1.0/fcc.xsd +9 -0
  761. data/spec/fixtures/xml/schema/xsd/isotc211/19110/gfc/1.1/featureCatalogue.xsd +671 -0
  762. data/spec/fixtures/xml/schema/xsd/isotc211/19110/gfc/1.1/gfc.xsd +13 -0
  763. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1/rbc.xsd +13 -0
  764. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1/rbcStubs.xsd +195 -0
  765. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.0/rbc.xsd +13 -0
  766. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.0/rbcStubs.xsd +195 -0
  767. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/AbstractCommonClasses.xsd +282 -0
  768. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/commonClasses.xsd +127 -0
  769. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/coordOps.xsd +676 -0
  770. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/coordRefSys.xsd +498 -0
  771. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/coordSys.xsd +844 -0
  772. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/coordinates.xsd +101 -0
  773. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/datum.xsd +474 -0
  774. data/spec/fixtures/xml/schema/xsd/isotc211/19111/-/rbc/3.1.1/rbc.xsd +18 -0
  775. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/cit/1.3/cit.xsd +12 -0
  776. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/cit/1.3/citation.xsd +445 -0
  777. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/cit/1.3.0/cit.xsd +12 -0
  778. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/cit/1.3.0/citation.xsd +445 -0
  779. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3/extent.xsd +243 -0
  780. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3/gex.xsd +16 -0
  781. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3.0/extent.xsd +243 -0
  782. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3.0/gex.xsd +16 -0
  783. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3.1/extent.xsd +244 -0
  784. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/gex/1.3.1/gex.xsd +15 -0
  785. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/lan/1.3/lan.xsd +13 -0
  786. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/lan/1.3/language.xsd +152 -0
  787. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/lan/1.3.0/lan.xsd +13 -0
  788. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/lan/1.3.0/language.xsd +152 -0
  789. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mas/1.3/applicationSchema.xsd +58 -0
  790. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mas/1.3/mas.xsd +16 -0
  791. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mas/1.3.0/applicationSchema.xsd +58 -0
  792. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mas/1.3.0/mas.xsd +16 -0
  793. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3/AbstractCommonClasses.xsd +378 -0
  794. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3/commonClasses.xsd +205 -0
  795. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3/mcc.xsd +12 -0
  796. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3.0/AbstractCommonClasses.xsd +378 -0
  797. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3.0/commonClasses.xsd +205 -0
  798. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mcc/1.3.0/mcc.xsd +12 -0
  799. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mco/1.3/constraints.xsd +171 -0
  800. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mco/1.3/mco.xsd +14 -0
  801. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mco/1.3.0/constraints.xsd +171 -0
  802. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mco/1.3.0/mco.xsd +14 -0
  803. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3/mda.xsd +13 -0
  804. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3/metadataApplication.xsd +207 -0
  805. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3.0/mda.xsd +13 -0
  806. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3.0/metadataApplication.xsd +207 -0
  807. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3.1/mda.xsd +13 -0
  808. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mda/1.3.1/metadataApplication.xsd +247 -0
  809. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3/mdb.xsd +11 -0
  810. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3/metadataBase.xsd +117 -0
  811. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3/metadataBaseMDAerror.xsd +116 -0
  812. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3.0/mdb.xsd +11 -0
  813. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3.0/metadataBase.xsd +117 -0
  814. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3.0/metadataBaseMDAerror.xsd +116 -0
  815. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3.1/mdb.xsd +11 -0
  816. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mdb/1.3.1/metadataBase.xsd +144 -0
  817. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mex/1.3/metadataExtension.xsd +138 -0
  818. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mex/1.3/mex.xsd +15 -0
  819. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mex/1.3.0/metadataExtension.xsd +138 -0
  820. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mex/1.3.0/mex.xsd +15 -0
  821. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mmi/1.3/maintenance.xsd +70 -0
  822. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mmi/1.3/mmi.xsd +14 -0
  823. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mmi/1.3.0/maintenance.xsd +70 -0
  824. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mmi/1.3.0/mmi.xsd +14 -0
  825. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mpc/1.3/mpc.xsd +14 -0
  826. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mpc/1.3/portrayalCatalogue.xsd +40 -0
  827. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mpc/1.3.0/mpc.xsd +14 -0
  828. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mpc/1.3.0/portrayalCatalogue.xsd +40 -0
  829. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3/content.xsd +368 -0
  830. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3/mrc.xsd +19 -0
  831. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3.0/content.xsd +368 -0
  832. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3.0/mrc.xsd +19 -0
  833. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3.1/content.xsd +366 -0
  834. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrc/1.3.1/mrc.xsd +13 -0
  835. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrd/1.3/distribution.xsd +232 -0
  836. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrd/1.3/mrd.xsd +13 -0
  837. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrd/1.3.0/distribution.xsd +232 -0
  838. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrd/1.3.0/mrd.xsd +13 -0
  839. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mri/1.3/identification.xsd +425 -0
  840. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mri/1.3/mri.xsd +16 -0
  841. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mri/1.3.0/identification.xsd +425 -0
  842. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mri/1.3.0/mri.xsd +16 -0
  843. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrl/1.3/lineage.xsd +130 -0
  844. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrl/1.3/mrl.xsd +15 -0
  845. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrl/1.3.0/lineage.xsd +130 -0
  846. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrl/1.3.0/mrl.xsd +15 -0
  847. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3/mrs.xsd +16 -0
  848. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3/referenceSystem.xsd +67 -0
  849. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3.0/mrs.xsd +16 -0
  850. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3.0/referenceSystem.xsd +67 -0
  851. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3.1/mrs.xsd +16 -0
  852. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/mrs/1.3.1/referenceSystem.xsd +66 -0
  853. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3/msr.xsd +17 -0
  854. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3/spatialRepresentation.xsd +326 -0
  855. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3.0/msr.xsd +17 -0
  856. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3.0/spatialRepresentation.xsd +326 -0
  857. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3.1/msr.xsd +15 -0
  858. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/msr/1.3.1/spatialRepresentation.xsd +326 -0
  859. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/srv/1.3/serviceInformation.xsd +252 -0
  860. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/srv/1.3/srv.xsd +14 -0
  861. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/srv/1.3.0/serviceInformation.xsd +252 -0
  862. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-1/srv/1.3.0/srv.xsd +14 -0
  863. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/acquisitionInformation.xsd +415 -0
  864. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/contentInformation.xsd +147 -0
  865. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/dataQualityInformation.xsd +214 -0
  866. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/gmi.xsd +23 -0
  867. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/metadataEntitySet.xsd +43 -0
  868. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.0/spatialRepresentationInformation.xsd +140 -0
  869. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/acquisitionInformation.xsd +415 -0
  870. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/contentInformation.xsd +147 -0
  871. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/dataQualityInformation.xsd +214 -0
  872. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/gmi.xsd +24 -0
  873. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/metadataEntitySet.xsd +43 -0
  874. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/gmi/1.1/spatialRepresentationInformation.xsd +142 -0
  875. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2/acquisitionInformationImagery.xsd +796 -0
  876. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2/mac.xsd +11 -0
  877. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2.0/acquisitionInformationImagery.xsd +796 -0
  878. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2.0/mac.xsd +11 -0
  879. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2.1/acquisitionInformationImagery.xsd +799 -0
  880. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mac/2.2.1/mac.xsd +10 -0
  881. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mrc/2.2/contentInformationImagery.xsd +161 -0
  882. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mrc/2.2.0/contentInformationImagery.xsd +161 -0
  883. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mrc/2.2.1/contentInformationImagery.xsd +159 -0
  884. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mrl/2.2/lineageImagery.xsd +312 -0
  885. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/mrl/2.2.0/lineageImagery.xsd +312 -0
  886. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/msr/2.2/spatialRepresentationImagery.xsd +138 -0
  887. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/msr/2.2.0/spatialRepresentationImagery.xsd +138 -0
  888. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-2/msr/2.2.1/spatialRepresentationImagery.xsd +145 -0
  889. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cat/1.0/cat.xsd +16 -0
  890. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cat/1.0/catalogues.xsd +59 -0
  891. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cat/1.0/codelistItem.xsd +63 -0
  892. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cat/1.0/crsItem.xsd +188 -0
  893. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cat/1.0/uomItem.xsd +45 -0
  894. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cit/1.0/cit.xsd +11 -0
  895. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cit/1.0/citation.xsd +400 -0
  896. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cit/2.0/cit.xsd +11 -0
  897. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/cit/2.0/citation.xsd +402 -0
  898. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gco/1.0/baseTypes.xsd +532 -0
  899. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gco/1.0/baseTypes2014.xsd +531 -0
  900. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gco/1.0/gco.xsd +16 -0
  901. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gcx/1.0/extendedTypes.xsd +97 -0
  902. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gcx/1.0/gcx.xsd +11 -0
  903. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gex/1.0/extent.xsd +207 -0
  904. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gex/1.0/gex.xsd +15 -0
  905. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gmw/1.0/gmlWrapperTypes.xsd +147 -0
  906. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gmw/1.0/gmlWrapperTypes2014.xsd +147 -0
  907. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/gmw/1.0/gmw.xsd +17 -0
  908. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/lan/1.0/lan.xsd +13 -0
  909. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/lan/1.0/language.xsd +141 -0
  910. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/1.0/acquisitionInformationImagery.xsd +424 -0
  911. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/1.0/mac.xsd +14 -0
  912. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/2.0/acquisitionInformationImagery.xsd +473 -0
  913. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/2.0/event.xsd +106 -0
  914. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/2.0/mac.xsd +15 -0
  915. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mac/2.0/metadataEntitySet.xsd +46 -0
  916. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mas/1.0/applicationSchema.xsd +53 -0
  917. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mas/1.0/mas.xsd +15 -0
  918. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mcc/1.0/AbstractCommonClasses.xsd +362 -0
  919. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mcc/1.0/commonClasses.xsd +179 -0
  920. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mcc/1.0/mcc.xsd +12 -0
  921. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mco/1.0/constraints.xsd +152 -0
  922. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mco/1.0/mco.xsd +13 -0
  923. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md1/1.0/md1.xsd +19 -0
  924. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md1/1.0/metadataWExtendedType.xsd +10 -0
  925. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md1/2.0/md1.xsd +19 -0
  926. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md1/2.0/metadataWExtendedType.xsd +10 -0
  927. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md2/1.0/md2.xsd +27 -0
  928. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md2/1.0/metadataWithExtensions.xsd +10 -0
  929. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md2/2.0/md2.xsd +27 -0
  930. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/md2/2.0/metadataWithExtensions.xsd +10 -0
  931. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mda/1.0/mda.xsd +13 -0
  932. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mda/1.0/metadataApplication.xsd +188 -0
  933. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mda/2.0/mda.xsd +13 -0
  934. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mda/2.0/metadataApplication.xsd +189 -0
  935. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdb/1.0/mdb.xsd +23 -0
  936. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdb/1.0/metadataBase.xsd +97 -0
  937. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdb/2.0/mdb.xsd +23 -0
  938. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdb/2.0/metadataBase.xsd +105 -0
  939. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mds/1.0/mds.xsd +59 -0
  940. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mds/1.0/metadataDataServices.xsd +10 -0
  941. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mds/2.0/mds.xsd +44 -0
  942. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mds/2.0/metadataDataServices.xsd +10 -0
  943. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdt/1.0/mdt.xsd +17 -0
  944. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdt/1.0/metadataTransfer.xsd +121 -0
  945. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdt/2.0/mdt.xsd +17 -0
  946. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mdt/2.0/metadataTransfer.xsd +121 -0
  947. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mex/1.0/metadataExtension.xsd +122 -0
  948. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mex/1.0/mex.xsd +13 -0
  949. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mmi/1.0/maintenance.xsd +63 -0
  950. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mmi/1.0/mmi.xsd +13 -0
  951. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mpc/1.0/mpc.xsd +13 -0
  952. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mpc/1.0/portrayalCatalogue.xsd +35 -0
  953. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/1.0/content.xsd +330 -0
  954. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/1.0/contentInformationImagery.xsd +160 -0
  955. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/1.0/mrc.xsd +18 -0
  956. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/2.0/content.xsd +334 -0
  957. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/2.0/contentInformationImagery.xsd +143 -0
  958. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrc/2.0/mrc.xsd +21 -0
  959. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrd/1.0/distribution.xsd +212 -0
  960. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrd/1.0/mrd.xsd +13 -0
  961. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mri/1.0/identification.xsd +385 -0
  962. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mri/1.0/mri.xsd +15 -0
  963. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/1.0/lineage.xsd +117 -0
  964. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/1.0/lineageImagery.xsd +168 -0
  965. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/1.0/mrl.xsd +14 -0
  966. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/2.0/lineage.xsd +118 -0
  967. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/2.0/lineageImagery.xsd +250 -0
  968. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrl/2.0/mrl.xsd +14 -0
  969. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrs/1.0/mrs.xsd +13 -0
  970. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/mrs/1.0/referenceSystem.xsd +47 -0
  971. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/1.0/msr.xsd +16 -0
  972. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/1.0/spatialRepresentation.xsd +288 -0
  973. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/1.0/spatialRepresentationImagery.xsd +113 -0
  974. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/2.0/msr.xsd +16 -0
  975. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/2.0/spatialRepresentation.xsd +296 -0
  976. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/msr/2.0/spatialRepresentationImagery.xsd +114 -0
  977. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/srv/2.0/serviceInformation.xsd +217 -0
  978. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/srv/2.0/srv.xsd +14 -0
  979. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/srv/2.1/serviceInformation.xsd +220 -0
  980. data/spec/fixtures/xml/schema/xsd/isotc211/19115/-3/srv/2.1/srv.xsd +14 -0
  981. data/spec/fixtures/xml/schema/xsd/isotc211/19119/-/srv/1.0/serviceMetadata.xsd +204 -0
  982. data/spec/fixtures/xml/schema/xsd/isotc211/19119/-/srv/1.0/serviceModel.xsd +230 -0
  983. data/spec/fixtures/xml/schema/xsd/isotc211/19119/-/srv/1.0/srv.xsd +13 -0
  984. data/spec/fixtures/xml/schema/xsd/isotc211/19119/srv/serviceMetadata.xsd +204 -0
  985. data/spec/fixtures/xml/schema/xsd/isotc211/19119/srv/serviceModel.xsd +238 -0
  986. data/spec/fixtures/xml/schema/xsd/isotc211/19119/srv/srv.xsd +13 -0
  987. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1/cis-0.xsd +17 -0
  988. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1/codeLists.xsd +68 -0
  989. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1/gridPoint.xsd +47 -0
  990. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1.0/cis-0.xsd +17 -0
  991. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1.0/codeLists.xsd +68 -0
  992. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/1.1.0/gridPoint.xsd +47 -0
  993. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/3.1.0/codeLists.xsd +68 -0
  994. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-/cis/3.1.0/gridPoint.xsd +47 -0
  995. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.0/coverage.xsd +185 -0
  996. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.0/gmlcovAll.xsd +21 -0
  997. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.0/grids.xsd +115 -0
  998. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1/coverage.xsd +188 -0
  999. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1/gmlcovAll.xsd +25 -0
  1000. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1/grids.xsd +119 -0
  1001. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1.0/coverage.xsd +188 -0
  1002. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1.0/gmlcovAll.xsd +25 -0
  1003. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/1.1.0/grids.xsd +119 -0
  1004. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/3.1.0/coverage.xsd +188 -0
  1005. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/3.1.0/gmlcovAll.xsd +23 -0
  1006. data/spec/fixtures/xml/schema/xsd/isotc211/19123/-2/cis/3.1.0/grids.xsd +119 -0
  1007. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/codeList.xsd +134 -0
  1008. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/groundControlPoints.xsd +239 -0
  1009. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/nonPhysicalSensorModel.xsd +321 -0
  1010. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/physicalSensorModel.xsd +62 -0
  1011. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/sensorModel.xsd +65 -0
  1012. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/sensorParameters.xsd +762 -0
  1013. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.0/spatialElements.xsd +497 -0
  1014. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/codeList.xsd +129 -0
  1015. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/groundControlPoints.xsd +235 -0
  1016. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/nonPhysicalSensorModel.xsd +321 -0
  1017. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/physicalSensorModel.xsd +62 -0
  1018. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/sensorModel.xsd +65 -0
  1019. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/sensorParameters.xsd +762 -0
  1020. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-1/smi/1.1.1/spatialElements.xsd +496 -0
  1021. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.0/codeList.xsd +349 -0
  1022. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.0/sensorModel.xsd +53 -0
  1023. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.0/sensorParameters.xsd +681 -0
  1024. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.0/spatialElements.xsd +902 -0
  1025. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.1/codeList.xsd +344 -0
  1026. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.1/sensorModel.xsd +49 -0
  1027. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.1/sensorParameters.xsd +676 -0
  1028. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-2/smi/1.1.1/spatialElements.xsd +897 -0
  1029. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-3/smi/1.1/smi.xsd +42 -0
  1030. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-3/smi/1.1.0/smi.xsd +42 -0
  1031. data/spec/fixtures/xml/schema/xsd/isotc211/19130/-3/smi/1.1.1/smi.xsd +42 -0
  1032. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-/dps/2.0/dps.xsd +1344 -0
  1033. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-/dps/2.0.0/dps.xsd +1344 -0
  1034. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-/dps/2.2/dps.xsd +1522 -0
  1035. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-/dps/2.2.0/dps.xsd +1522 -0
  1036. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-/dps/2.2.1/dps.xsd +1522 -0
  1037. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-1/dps/2.0/dps.xsd +1339 -0
  1038. data/spec/fixtures/xml/schema/xsd/isotc211/19131/-1/dps/2.2.0/dps.xsd +1540 -0
  1039. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.0/core.xsd +349 -0
  1040. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.0/extended.xsd +1074 -0
  1041. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.0/hierarchy.xsd +57 -0
  1042. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.0/pir.xsd +13 -0
  1043. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1/core.xsd +344 -0
  1044. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1/extended.xsd +1076 -0
  1045. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1/hierarchy.xsd +58 -0
  1046. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1/pir.xsd +15 -0
  1047. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1.0/core.xsd +344 -0
  1048. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1.0/extended.xsd +1076 -0
  1049. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1.0/hierarchy.xsd +58 -0
  1050. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-1/pir/1.1.0/pir.xsd +15 -0
  1051. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/pre/1.0/abstract.xsd +42 -0
  1052. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/pre/1.0/pre.xsd +4 -0
  1053. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/pre/1.2.0/abstract.xsd +44 -0
  1054. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/pre/1.2.0/pre.xsd +11 -0
  1055. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/reg/1.0/reg.xsd +8 -0
  1056. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/reg/1.0/registration.xsd +562 -0
  1057. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/reg/1.2.0/reg.xsd +22 -0
  1058. data/spec/fixtures/xml/schema/xsd/isotc211/19135/-2/reg/1.2.0/registration.xsd +590 -0
  1059. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/basicTypes.xsd +275 -0
  1060. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/coordinateOperations.xsd +534 -0
  1061. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/coordinateReferenceSystems.xsd +379 -0
  1062. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/coordinateSystems.xsd +303 -0
  1063. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/coverage.xsd +298 -0
  1064. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/datums.xsd +293 -0
  1065. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/defaultStyle.xsd +462 -0
  1066. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/deprecatedTypes.xsd +1139 -0
  1067. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/dictionary.xsd +95 -0
  1068. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/direction.xsd +90 -0
  1069. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/dynamicFeature.xsd +114 -0
  1070. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/feature.xsd +99 -0
  1071. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/geometryAggregates.xsd +203 -0
  1072. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/geometryBasic0d1d.xsd +283 -0
  1073. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/geometryBasic2d.xsd +130 -0
  1074. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/geometryComplexes.xsd +101 -0
  1075. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/geometryPrimitives.xsd +852 -0
  1076. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/gml.xsd +25 -0
  1077. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/gmlBase.xsd +191 -0
  1078. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/grids.xsd +70 -0
  1079. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/measures.xsd +74 -0
  1080. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/observation.xsd +100 -0
  1081. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/referenceSystems.xsd +78 -0
  1082. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/temporal.xsd +274 -0
  1083. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/temporalReferenceSystems.xsd +194 -0
  1084. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/temporalTopology.xsd +124 -0
  1085. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/topology.xsd +391 -0
  1086. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/units.xsd +168 -0
  1087. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-/gml/1.0/valueObjects.xsd +210 -0
  1088. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-1/gmw/1.1/gmlWrapperTypes.xsd +160 -0
  1089. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-1/gmw/1.1/gmw.xsd +27 -0
  1090. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-1/gmw/1.1.0/gmlWrapperTypes.xsd +160 -0
  1091. data/spec/fixtures/xml/schema/xsd/isotc211/19136/-1/gmw/1.1.0/gmw.xsd +27 -0
  1092. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2/cat.xsd +18 -0
  1093. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2/catalogues.xsd +63 -0
  1094. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2/codelistItem.xsd +64 -0
  1095. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2/crsItem.xsd +200 -0
  1096. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2/uomItem.xsd +49 -0
  1097. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2.0/cat.xsd +18 -0
  1098. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2.0/catalogues.xsd +63 -0
  1099. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2.0/codelistItem.xsd +64 -0
  1100. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2.0/crsItem.xsd +200 -0
  1101. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/cat/1.2.0/uomItem.xsd +49 -0
  1102. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gco/1.0/basicTypes.xsd +439 -0
  1103. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gco/1.0/gco.xsd +18 -0
  1104. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gco/1.0/gcoBase.xsd +71 -0
  1105. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/applicationSchema.xsd +50 -0
  1106. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/citation.xsd +283 -0
  1107. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/constraints.xsd +114 -0
  1108. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/content.xsd +197 -0
  1109. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/dataQuality.xsd +563 -0
  1110. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/distribution.xsd +210 -0
  1111. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/extent.xsd +216 -0
  1112. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/freeText.xsd +130 -0
  1113. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/gmd.xsd +18 -0
  1114. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/identification.xsd +356 -0
  1115. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/maintenance.xsd +95 -0
  1116. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/metadataApplication.xsd +183 -0
  1117. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/metadataEntity.xsd +78 -0
  1118. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/metadataExtension.xsd +107 -0
  1119. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/portrayalCatalogue.xsd +44 -0
  1120. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/referenceSystem.xsd +108 -0
  1121. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmd/1.0/spatialRepresentation.xsd +246 -0
  1122. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/catalogues.xsd +121 -0
  1123. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/codelistItem.xsd +179 -0
  1124. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/crsItem.xsd +1041 -0
  1125. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/extendedTypes.xsd +83 -0
  1126. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/gmx.xsd +18 -0
  1127. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/gmxUsage.xsd +136 -0
  1128. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gmx/1.0/uomItem.xsd +173 -0
  1129. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gsr/1.0/gsr.xsd +18 -0
  1130. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gsr/1.0/spatialReferencing.xsd +34 -0
  1131. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gss/1.0/geometry.xsd +45 -0
  1132. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gss/1.0/gss.xsd +18 -0
  1133. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gts/1.0/gts.xsd +18 -0
  1134. data/spec/fixtures/xml/schema/xsd/isotc211/19139/-/gts/1.0/temporalObjects.xsd +44 -0
  1135. data/spec/fixtures/xml/schema/xsd/isotc211/19155/gpi/1.0/gpi.xsd +16 -0
  1136. data/spec/fixtures/xml/schema/xsd/isotc211/19155/gpi/1.0/placeIdentifier.xsd +75 -0
  1137. data/spec/fixtures/xml/schema/xsd/isotc211/19155/gpi/1.0/sampleGMLApplicationSchema.xsd +83 -0
  1138. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqc/1.2/abstract.xsd +44 -0
  1139. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqc/1.2/dqc.xsd +16 -0
  1140. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqc/1.2.0/abstract.xsd +44 -0
  1141. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqc/1.2.0/dqc.xsd +16 -0
  1142. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqm/1.2/dqm.xsd +19 -0
  1143. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqm/1.2/qualityMeasures.xsd +332 -0
  1144. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqm/1.2.0/dqm.xsd +19 -0
  1145. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/dqm/1.2.0/qualityMeasures.xsd +332 -0
  1146. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/dataQualityElement.xsd +583 -0
  1147. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/dataQualityEvaluation.xsd +199 -0
  1148. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/dataQualityImagery.xsd +75 -0
  1149. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/dataQualityResult.xsd +213 -0
  1150. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/mdq.xsd +22 -0
  1151. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2/metaquality.xsd +93 -0
  1152. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/dataQualityElement.xsd +583 -0
  1153. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/dataQualityEvaluation.xsd +199 -0
  1154. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/dataQualityImagery.xsd +75 -0
  1155. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/dataQualityResult.xsd +213 -0
  1156. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/mdq.xsd +22 -0
  1157. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-/mdq/1.2.0/metaquality.xsd +93 -0
  1158. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqc/1.0.0/dataQualityCommon.xsd +33 -0
  1159. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqc/1.0.0/dqc.xsd +14 -0
  1160. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqc/1.0.1/dataQualityCommon.xsd +43 -0
  1161. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqc/1.0.1/dqc.xsd +17 -0
  1162. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqm/1.0.0/dataQualityMeasure.xsd +376 -0
  1163. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqm/1.0.0/dqm.xsd +11 -0
  1164. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqm/1.0.1/dataQualityMeasure.xsd +367 -0
  1165. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/dqm/1.0.1/dqm.xsd +11 -0
  1166. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.0/dataQuality.xsd +570 -0
  1167. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.0/dataQualityEvaluation.xsd +227 -0
  1168. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.0/dataQualityResult.xsd +191 -0
  1169. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.0/mdq.xsd +14 -0
  1170. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.0/metaquality.xsd +106 -0
  1171. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.1/dataQuality.xsd +581 -0
  1172. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.1/dataQualityEvaluation.xsd +227 -0
  1173. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.1/dataQualityResult.xsd +198 -0
  1174. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.1/mdq.xsd +14 -0
  1175. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-1/mdq/1.0.1/metaquality.xsd +102 -0
  1176. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/dqc/1.0/abstract.xsd +43 -0
  1177. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/dqc/1.0/dqc.xsd +15 -0
  1178. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/dqm/1.0/dqm.xsd +15 -0
  1179. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/dqm/1.0/qualityMeasures.xsd +303 -0
  1180. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/dataQualityElement.xsd +554 -0
  1181. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/dataQualityEvaluation.xsd +182 -0
  1182. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/dataQualityImagery.xsd +72 -0
  1183. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/dataQualityResult.xsd +140 -0
  1184. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/mdq.xsd +21 -0
  1185. data/spec/fixtures/xml/schema/xsd/isotc211/19157/-2/mdq/1.0/metaquality.xsd +89 -0
  1186. data/spec/fixtures/xml/schema/xsd/isotc211/19160/-4/patdl/2.7.3/PATDL.v.2.7.3.xsd +517 -0
  1187. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1/IE_Imagery.xsd +520 -0
  1188. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1/IE_ImageryAndGriddedData.xsd +222 -0
  1189. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1/IE_ThematicGriddedData.xsd +117 -0
  1190. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1/igd.xsd +14 -0
  1191. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.0/IE_Imagery.xsd +520 -0
  1192. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.0/IE_ImageryAndGriddedData.xsd +222 -0
  1193. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.0/IE_ThematicGriddedData.xsd +117 -0
  1194. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.0/igd.xsd +14 -0
  1195. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.1/IE_Imagery.xsd +518 -0
  1196. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.1/IE_ImageryAndGriddedData.xsd +213 -0
  1197. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.1/IE_ThematicGriddedData.xsd +116 -0
  1198. data/spec/fixtures/xml/schema/xsd/isotc211/19163/-1/igd/1.1.1/igd.xsd +15 -0
  1199. data/spec/fixtures/xml/schema/xsd/isotc211/19165/-1/gpm/1.0.0/geospatialPreservationMetadata.xsd +872 -0
  1200. data/spec/fixtures/xml/schema/xsd/isotc211/19165/-1/gpm/1.0.0/gpm.xsd +11 -0
  1201. data/spec/fixtures/xml/schema/xsd/isotc211/19165/gpm/1.0/geospatialPreservationMetadata.xsd +385 -0
  1202. data/spec/fixtures/xml/schema/xsd/isotc211/19165/gpm/1.0/gpm.xsd +8 -0
  1203. data/spec/fixtures/xml/schema/xsd/metaschema-datatypes.xsd +263 -0
  1204. data/spec/fixtures/xml/schema/xsd/metaschema-markup-line.xsd +9 -0
  1205. data/spec/fixtures/xml/schema/xsd/metaschema-markup-multiline.xsd +135 -0
  1206. data/spec/fixtures/xml/schema/xsd/metaschema-meta-constraints.xsd +39 -0
  1207. data/spec/fixtures/xml/schema/xsd/metaschema-prose-base.xsd +82 -0
  1208. data/spec/fixtures/xml/schema/xsd/metaschema-prose-module.xsd +5 -0
  1209. data/spec/fixtures/xml/schema/xsd/metaschema.xsd +1344 -0
  1210. data/spec/fixtures/xml/schema/xsd/omml_schema.xsd +1528 -0
  1211. data/spec/fixtures/xml/schema/xsd/smil20/rdf.xsd +16 -0
  1212. data/spec/fixtures/xml/schema/xsd/smil20/smil20-AccessKeyTiming.xsd +33 -0
  1213. data/spec/fixtures/xml/schema/xsd/smil20/smil20-AudioLayout.xsd +32 -0
  1214. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicAnimation.xsd +35 -0
  1215. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicContentControl.xsd +49 -0
  1216. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicInlineTiming.xsd +34 -0
  1217. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicLayout.xsd +34 -0
  1218. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicLinking.xsd +34 -0
  1219. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicMedia.xsd +39 -0
  1220. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicTimeContainers.xsd +37 -0
  1221. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BasicTransitions.xsd +36 -0
  1222. data/spec/fixtures/xml/schema/xsd/smil20/smil20-BrushMedia.xsd +32 -0
  1223. data/spec/fixtures/xml/schema/xsd/smil20/smil20-CustomTestAttributes.xsd +33 -0
  1224. data/spec/fixtures/xml/schema/xsd/smil20/smil20-EventTiming.xsd +33 -0
  1225. data/spec/fixtures/xml/schema/xsd/smil20/smil20-ExclTimeContainers.xsd +37 -0
  1226. data/spec/fixtures/xml/schema/xsd/smil20/smil20-FillDefault.xsd +32 -0
  1227. data/spec/fixtures/xml/schema/xsd/smil20/smil20-HierarchicalLayout.xsd +46 -0
  1228. data/spec/fixtures/xml/schema/xsd/smil20/smil20-HostLanguage.xsd +85 -0
  1229. data/spec/fixtures/xml/schema/xsd/smil20/smil20-InlineTransitions.xsd +35 -0
  1230. data/spec/fixtures/xml/schema/xsd/smil20/smil20-IntegrationSet.xsd +72 -0
  1231. data/spec/fixtures/xml/schema/xsd/smil20/smil20-LinkingAttributes.xsd +40 -0
  1232. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaAccessibility.xsd +34 -0
  1233. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaClipMarkers.xsd +35 -0
  1234. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaClipping.xsd +35 -0
  1235. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaDescription.xsd +35 -0
  1236. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaMarkerTiming.xsd +33 -0
  1237. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MediaParam.xsd +34 -0
  1238. data/spec/fixtures/xml/schema/xsd/smil20/smil20-Metainformation.xsd +33 -0
  1239. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MinMaxTiming.xsd +33 -0
  1240. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MultiArcTiming.xsd +33 -0
  1241. data/spec/fixtures/xml/schema/xsd/smil20/smil20-MultiWindowLayout.xsd +32 -0
  1242. data/spec/fixtures/xml/schema/xsd/smil20/smil20-ObjectLinking.xsd +33 -0
  1243. data/spec/fixtures/xml/schema/xsd/smil20/smil20-PrefetchControl.xsd +31 -0
  1244. data/spec/fixtures/xml/schema/xsd/smil20/smil20-RepeatTiming.xsd +34 -0
  1245. data/spec/fixtures/xml/schema/xsd/smil20/smil20-RepeatValueTiming.xsd +33 -0
  1246. data/spec/fixtures/xml/schema/xsd/smil20/smil20-RestartDefault.xsd +32 -0
  1247. data/spec/fixtures/xml/schema/xsd/smil20/smil20-RestartTiming.xsd +32 -0
  1248. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SkipContentControl.xsd +32 -0
  1249. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SplineAnimation.xsd +34 -0
  1250. data/spec/fixtures/xml/schema/xsd/smil20/smil20-Structure.xsd +34 -0
  1251. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SyncBehavior.xsd +33 -0
  1252. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SyncBehaviorDefault.xsd +33 -0
  1253. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SyncMaster.xsd +32 -0
  1254. data/spec/fixtures/xml/schema/xsd/smil20/smil20-SyncbaseTiming.xsd +33 -0
  1255. data/spec/fixtures/xml/schema/xsd/smil20/smil20-TimeContainerAttributes.xsd +35 -0
  1256. data/spec/fixtures/xml/schema/xsd/smil20/smil20-TimeManipulations.xsd +35 -0
  1257. data/spec/fixtures/xml/schema/xsd/smil20/smil20-TransitionModifiers.xsd +37 -0
  1258. data/spec/fixtures/xml/schema/xsd/smil20/smil20-WallclockTiming.xsd +33 -0
  1259. data/spec/fixtures/xml/schema/xsd/smil20/smil20-animate.xsd +229 -0
  1260. data/spec/fixtures/xml/schema/xsd/smil20/smil20-content.xsd +148 -0
  1261. data/spec/fixtures/xml/schema/xsd/smil20/smil20-language.xsd +834 -0
  1262. data/spec/fixtures/xml/schema/xsd/smil20/smil20-layout.xsd +211 -0
  1263. data/spec/fixtures/xml/schema/xsd/smil20/smil20-linking.xsd +117 -0
  1264. data/spec/fixtures/xml/schema/xsd/smil20/smil20-media.xsd +175 -0
  1265. data/spec/fixtures/xml/schema/xsd/smil20/smil20-meta.xsd +44 -0
  1266. data/spec/fixtures/xml/schema/xsd/smil20/smil20-struct.xsd +47 -0
  1267. data/spec/fixtures/xml/schema/xsd/smil20/smil20-timemanip.xsd +34 -0
  1268. data/spec/fixtures/xml/schema/xsd/smil20/smil20-timing.xsd +344 -0
  1269. data/spec/fixtures/xml/schema/xsd/smil20/smil20-transitions.xsd +138 -0
  1270. data/spec/fixtures/xml/schema/xsd/smil20/smil20-utility.xsd +57 -0
  1271. data/spec/fixtures/xml/schema/xsd/smil20/smil20.xsd +86 -0
  1272. data/spec/fixtures/xml/schema/xsd/smil20/xml-mod.xsd +25 -0
  1273. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/advanced_encodings.xsd +186 -0
  1274. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/basic_types.xsd +147 -0
  1275. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/block_components.xsd +163 -0
  1276. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/choice_components.xsd +56 -0
  1277. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/examples/security.xsd +15 -0
  1278. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/record_components.xsd +95 -0
  1279. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/simple_components.xsd +536 -0
  1280. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/simple_encodings.xsd +93 -0
  1281. data/spec/fixtures/xml/schema/xsd/sweCommon/2.0.1/swe.xsd +14 -0
  1282. data/spec/fixtures/xml/schema/xsd/test_schema.lxr +0 -0
  1283. data/spec/fixtures/xml/schema/xsd/test_schema.xsd +24 -0
  1284. data/spec/fixtures/xml/schema/xsd/unitsml-v1.0-csd03.xsd +1333 -0
  1285. data/spec/fixtures/xml/schema/xsd/unitsml-v1.0-csd04.xsd +1334 -0
  1286. data/spec/fixtures/xml/schema/xsd/validation_config.yml +14 -0
  1287. data/spec/fixtures/xml/special_char.xml +3 -4
  1288. data/spec/fixtures/xml/user.xsd +14 -10
  1289. data/spec/fixtures/yamls_range_concept.rb +139 -0
  1290. data/spec/lutaml/key_value/transformation/collection_serializer_spec.rb +213 -0
  1291. data/spec/lutaml/key_value/transformation/rule_compiler_spec.rb +229 -0
  1292. data/spec/lutaml/key_value/transformation/value_serializer_spec.rb +216 -0
  1293. data/spec/lutaml/key_value/transformation_spec.rb +292 -0
  1294. data/spec/lutaml/model/attribute_collection_spec.rb +9 -6
  1295. data/spec/lutaml/model/attribute_form_default_spec.rb +252 -0
  1296. data/spec/lutaml/model/attribute_spec.rb +328 -38
  1297. data/spec/lutaml/model/cached_type_resolver_spec.rb +362 -0
  1298. data/spec/lutaml/model/cdata_spec.rb +180 -102
  1299. data/spec/lutaml/model/choice_spec.rb +37 -7
  1300. data/spec/lutaml/model/cli_spec.rb +452 -0
  1301. data/spec/lutaml/model/collection_index_spec.rb +347 -0
  1302. data/spec/lutaml/model/collection_mutation_spec.rb +124 -0
  1303. data/spec/lutaml/model/collection_spec.rb +580 -155
  1304. data/spec/lutaml/model/collection_validation_spec.rb +736 -0
  1305. data/spec/lutaml/model/comparable_model_spec.rb +75 -0
  1306. data/spec/lutaml/model/compiled_rule_spec.rb +364 -0
  1307. data/spec/lutaml/model/consolidation_spec.rb +295 -0
  1308. data/spec/lutaml/model/context_registry_spec.rb +269 -0
  1309. data/spec/lutaml/model/custom_bibtex_adapter_spec.rb +21 -7
  1310. data/spec/lutaml/model/custom_collection_spec.rb +321 -27
  1311. data/spec/lutaml/model/custom_model_spec.rb +13 -10
  1312. data/spec/lutaml/model/custom_serialization_spec.rb +12 -14
  1313. data/spec/lutaml/model/custom_vobject_adapter_spec.rb +36 -16
  1314. data/spec/lutaml/model/default_register_spec.rb +852 -0
  1315. data/spec/lutaml/model/defaults_spec.rb +57 -6
  1316. data/spec/lutaml/model/delegation_spec.rb +184 -110
  1317. data/spec/lutaml/model/derived_attribute_serialization_spec.rb +33 -0
  1318. data/spec/lutaml/model/dynamic_attribute_spec.rb +112 -0
  1319. data/spec/lutaml/model/encoding_spec.rb +281 -0
  1320. data/spec/lutaml/model/enum_spec.rb +46 -2
  1321. data/spec/lutaml/model/except_spec.rb +240 -0
  1322. data/spec/lutaml/model/finalization_cache_spec.rb +88 -0
  1323. data/spec/lutaml/model/global_context_spec.rb +421 -0
  1324. data/spec/lutaml/model/global_register_spec.rb +153 -36
  1325. data/spec/lutaml/model/group_spec.rb +193 -54
  1326. data/spec/lutaml/model/hash/adapter_spec.rb +5 -3
  1327. data/spec/lutaml/model/import_registry_spec.rb +295 -0
  1328. data/spec/lutaml/model/included_spec.rb +10 -17
  1329. data/spec/lutaml/model/inheritance_spec.rb +6 -6
  1330. data/spec/lutaml/model/json_adapter_spec.rb +13 -6
  1331. data/spec/lutaml/model/json_spec.rb +33 -0
  1332. data/spec/lutaml/model/key_value_data_model/key_value_element_spec.rb +320 -0
  1333. data/spec/lutaml/model/key_value_mapping_spec.rb +12 -2
  1334. data/spec/lutaml/model/lazy_collection_spec.rb +208 -0
  1335. data/spec/lutaml/model/liquefiable_spec.rb +263 -24
  1336. data/spec/lutaml/model/logger_spec.rb +68 -0
  1337. data/spec/lutaml/model/map_all_spec.rb +36 -11
  1338. data/spec/lutaml/model/map_content_spec.rb +4 -4
  1339. data/spec/lutaml/model/mapping_rule_perf_guard_spec.rb +71 -0
  1340. data/spec/lutaml/model/mixed_content_spec.rb +481 -171
  1341. data/spec/lutaml/model/model_transformer_spec.rb +678 -0
  1342. data/spec/lutaml/model/multiple_mapping_spec.rb +71 -39
  1343. data/spec/lutaml/model/namespace_versioning_spec.rb +390 -0
  1344. data/spec/lutaml/model/one_entry_cache_spec.rb +114 -0
  1345. data/spec/lutaml/model/ordered_content_spec.rb +115 -24
  1346. data/spec/lutaml/model/polymorphic_spec.rb +29 -6
  1347. data/spec/lutaml/model/processing_instruction_spec.rb +375 -0
  1348. data/spec/lutaml/model/{register/key_value_spec.rb → register_key_value_spec.rb} +57 -5
  1349. data/spec/lutaml/model/register_spec.rb +235 -5
  1350. data/spec/lutaml/model/render_empty_spec.rb +143 -6
  1351. data/spec/lutaml/model/render_nil_spec.rb +15 -10
  1352. data/spec/lutaml/model/root_mappings_spec.rb +16 -6
  1353. data/spec/lutaml/model/rule_value_extractor_spec.rb +13 -44
  1354. data/spec/lutaml/model/runtime_compatibility_spec.rb +36 -0
  1355. data/spec/lutaml/model/schema/generator/definitions_collection_spec.rb +4 -0
  1356. data/spec/lutaml/model/schema/json_schema_spec.rb +7 -1
  1357. data/spec/lutaml/model/schema/relaxng_schema_spec.rb +1 -1
  1358. data/spec/lutaml/model/schema/renderer_spec.rb +128 -0
  1359. data/spec/lutaml/model/schema/xsd_schema_spec.rb +1 -1
  1360. data/spec/lutaml/model/sequence_spec.rb +460 -15
  1361. data/spec/lutaml/model/serializable_spec.rb +212 -12
  1362. data/spec/lutaml/model/serializable_validation_spec.rb +3 -2
  1363. data/spec/lutaml/model/serialize_perf_guard_spec.rb +100 -0
  1364. data/spec/lutaml/model/services/default_value_resolver_spec.rb +162 -0
  1365. data/spec/lutaml/model/simple_model_spec.rb +4 -4
  1366. data/spec/lutaml/model/toml_adapter_spec.rb +11 -4
  1367. data/spec/lutaml/model/toml_spec.rb +46 -2
  1368. data/spec/lutaml/model/transformation_builder_spec.rb +283 -0
  1369. data/spec/lutaml/model/transformation_spec.rb +165 -236
  1370. data/spec/lutaml/model/type/base64_binary_spec.rb +202 -0
  1371. data/spec/lutaml/model/type/date_spec.rb +132 -0
  1372. data/spec/lutaml/model/type/date_time_spec.rb +54 -2
  1373. data/spec/lutaml/model/type/decimal_spec.rb +1 -1
  1374. data/spec/lutaml/model/type/duration_spec.rb +185 -0
  1375. data/spec/lutaml/model/type/hex_binary_spec.rb +225 -0
  1376. data/spec/lutaml/model/type/integer_spec.rb +1 -1
  1377. data/spec/lutaml/model/type/qname_spec.rb +246 -0
  1378. data/spec/lutaml/model/type/reference_integration_spec.rb +532 -0
  1379. data/spec/lutaml/model/type/reference_spec.rb +293 -0
  1380. data/spec/lutaml/model/type/symbol_spec.rb +322 -0
  1381. data/spec/lutaml/model/type/time_spec.rb +6 -5
  1382. data/spec/lutaml/model/type/time_without_date_spec.rb +1 -1
  1383. data/spec/lutaml/model/type/uninitialized_class_spec.rb +110 -0
  1384. data/spec/lutaml/model/type/uri_spec.rb +176 -0
  1385. data/spec/lutaml/model/type/value_xml_mapping_spec.rb +162 -0
  1386. data/spec/lutaml/model/type_context_spec.rb +370 -0
  1387. data/spec/lutaml/model/type_registry_spec.rb +313 -0
  1388. data/spec/lutaml/model/type_resolver_spec.rb +278 -0
  1389. data/spec/lutaml/model/type_spec.rb +7 -8
  1390. data/spec/lutaml/model/type_substitution_spec.rb +172 -0
  1391. data/spec/lutaml/model/utils_spec.rb +39 -24
  1392. data/spec/lutaml/model/value_map_spec.rb +2 -2
  1393. data/spec/lutaml/model/value_transformation_comprehensive_spec.rb +676 -0
  1394. data/spec/lutaml/model/with_child_mapping_spec.rb +1 -1
  1395. data/spec/lutaml/model/xml_decoupling_spec.rb +436 -0
  1396. data/spec/lutaml/model/xsd_form_default_patterns_spec.rb +664 -0
  1397. data/spec/lutaml/model/xsd_patterns_spec.rb +278 -0
  1398. data/spec/lutaml/model/xsd_type_spec.rb +345 -0
  1399. data/spec/lutaml/model/xsd_type_validation_spec.rb +442 -0
  1400. data/spec/lutaml/model/yamls/standard_adapter_spec.rb +2 -2
  1401. data/spec/lutaml/model/yamls_range_spec.rb +393 -0
  1402. data/spec/lutaml/model/yamls_sequence_spec.rb +245 -0
  1403. data/spec/lutaml/xml/adapter/nokogiri_adapter_spec.rb +130 -0
  1404. data/spec/lutaml/xml/adapter/oga_adapter_spec.rb +135 -0
  1405. data/spec/lutaml/xml/adapter/ox_adapter_spec.rb +101 -0
  1406. data/spec/lutaml/xml/adapter/rexml_adapter_spec.rb +101 -0
  1407. data/spec/lutaml/xml/adapter/xml_namespace_spec.rb +531 -0
  1408. data/spec/lutaml/xml/builder/builder_spec.rb +216 -0
  1409. data/spec/lutaml/xml/compiled_rule_namespace_spec.rb +405 -0
  1410. data/spec/lutaml/xml/conformance/xml_namespaces_spec.rb +580 -0
  1411. data/spec/lutaml/xml/conformance/xml_schema_instance_spec.rb +266 -0
  1412. data/spec/lutaml/xml/data_model_spec.rb +300 -0
  1413. data/spec/lutaml/xml/decisions/decision_engine_spec.rb +242 -0
  1414. data/spec/lutaml/xml/decisions/decision_spec.rb +217 -0
  1415. data/spec/lutaml/xml/decisions/element_prefix_resolver_spec.rb +198 -0
  1416. data/spec/lutaml/xml/declaration_planner_spec.rb +524 -0
  1417. data/spec/lutaml/xml/default_namespace_spec.rb +190 -0
  1418. data/spec/lutaml/{model/xml → xml}/derived_attributes_spec.rb +2 -2
  1419. data/spec/lutaml/xml/doctype_preservation_spec.rb +323 -0
  1420. data/spec/lutaml/xml/doubly_defined_namespace_spec.rb +415 -0
  1421. data/spec/lutaml/xml/dual_namespace_element_spec.rb +181 -0
  1422. data/spec/lutaml/xml/element_spec.rb +28 -0
  1423. data/spec/lutaml/xml/encoding_normalizer_spec.rb +215 -0
  1424. data/spec/lutaml/xml/enhanced_mapping_spec.rb +692 -0
  1425. data/spec/lutaml/xml/entity_fragmentation_spec.rb +583 -0
  1426. data/spec/lutaml/xml/format_chooser_spec.rb +0 -0
  1427. data/spec/lutaml/xml/fpi_namespace_spec.rb +145 -0
  1428. data/spec/lutaml/{model/xml/namespace_spec.rb → xml/general_namespace_spec.rb} +6 -5
  1429. data/spec/lutaml/xml/mapping_finalization_guard_spec.rb +83 -0
  1430. data/spec/lutaml/xml/mapping_rule_spec.rb +98 -0
  1431. data/spec/lutaml/xml/mapping_spec.rb +1147 -0
  1432. data/spec/lutaml/xml/model_transform_guard_spec.rb +126 -0
  1433. data/spec/lutaml/{model/xml → xml}/namespace/nested_with_explicit_namespace_spec.rb +8 -5
  1434. data/spec/lutaml/xml/namespace/w3c_reserved_warning_spec.rb +152 -0
  1435. data/spec/lutaml/xml/namespace_alias_prefix_root_spec.rb +130 -0
  1436. data/spec/lutaml/xml/namespace_alias_spec.rb +263 -0
  1437. data/spec/lutaml/xml/namespace_aware_parsing_spec.rb +219 -0
  1438. data/spec/lutaml/xml/namespace_backward_compatibility_spec.rb +48 -0
  1439. data/spec/lutaml/xml/namespace_bound_element_roundtrip_spec.rb +433 -0
  1440. data/spec/lutaml/xml/namespace_constant_spec.rb +383 -0
  1441. data/spec/lutaml/xml/namespace_force_prefix_spec.rb +113 -0
  1442. data/spec/lutaml/xml/namespace_format_preservation_spec.rb +49 -0
  1443. data/spec/lutaml/xml/namespace_inheritance_deep_spec.rb +162 -0
  1444. data/spec/lutaml/xml/namespace_inheritance_override_spec.rb +316 -0
  1445. data/spec/lutaml/xml/namespace_inheritance_resolver_spec.rb +0 -0
  1446. data/spec/lutaml/xml/namespace_inheritance_spec.rb +966 -0
  1447. data/spec/lutaml/xml/namespace_integration_spec.rb +277 -0
  1448. data/spec/lutaml/xml/namespace_missing_prefix_spec.rb +178 -0
  1449. data/spec/lutaml/xml/namespace_no_hoisting_spec.rb +172 -0
  1450. data/spec/lutaml/xml/namespace_placement_spec.rb +265 -0
  1451. data/spec/lutaml/xml/namespace_preservation_spec.rb +427 -0
  1452. data/spec/lutaml/xml/namespace_principles_spec.rb +909 -0
  1453. data/spec/lutaml/xml/namespace_resolution_strategy_spec.rb +273 -0
  1454. data/spec/lutaml/xml/namespace_scope_declare_spec.rb +205 -0
  1455. data/spec/lutaml/xml/namespace_scope_spec.rb +389 -0
  1456. data/spec/lutaml/xml/namespace_scope_vcard_spec.rb +616 -0
  1457. data/spec/lutaml/xml/namespace_spec.rb +712 -0
  1458. data/spec/lutaml/xml/namespace_three_phase_spec.rb +310 -0
  1459. data/spec/lutaml/xml/nil_optional_element_namespace_spec.rb +84 -0
  1460. data/spec/lutaml/xml/ooxml_namespace_spec.rb +177 -0
  1461. data/spec/lutaml/xml/ordered_method_spec.rb +109 -0
  1462. data/spec/lutaml/xml/prefix_control_spec.rb +286 -0
  1463. data/spec/lutaml/{model/register/xml_spec.rb → xml/register_spec.rb} +75 -21
  1464. data/spec/lutaml/xml/reusable_mapping_spec.rb +148 -0
  1465. data/spec/lutaml/xml/reused_elements_namespace_spec.rb +85 -0
  1466. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/attribute_group_spec.rb +9 -3
  1467. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/attribute_spec.rb +11 -7
  1468. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/choice_spec.rb +5 -2
  1469. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/complex_content_restriction_spec.rb +7 -2
  1470. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/complex_content_spec.rb +5 -1
  1471. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/complex_type_spec.rb +49 -20
  1472. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/element_spec.rb +9 -4
  1473. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/group_spec.rb +9 -5
  1474. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/restriction_spec.rb +1 -0
  1475. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/sequence_spec.rb +10 -4
  1476. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/simple_content_spec.rb +9 -3
  1477. data/spec/lutaml/{model/schema/xml_compiler → xml/schema/compiler}/simple_type_spec.rb +10 -7
  1478. data/spec/lutaml/{model/schema/xml_compiler_spec.rb → xml/schema/compiler_spec.rb} +219 -94
  1479. data/spec/lutaml/xml/schema/xsd/errors/error_context_spec.rb +65 -0
  1480. data/spec/lutaml/xml/schema/xsd/errors/suggestion_spec.rb +77 -0
  1481. data/spec/lutaml/xml/schema/xsd/file_validation_result_spec.rb +131 -0
  1482. data/spec/lutaml/xml/schema/xsd/glob_spec.rb +318 -0
  1483. data/spec/lutaml/xml/schema/xsd/liquid_methods/attribute_and_group_spec.rb +76 -0
  1484. data/spec/lutaml/xml/schema/xsd/liquid_methods/complex_type_spec.rb +159 -0
  1485. data/spec/lutaml/xml/schema/xsd/liquid_methods/containers_spec.rb +104 -0
  1486. data/spec/lutaml/xml/schema/xsd/liquid_methods/element_spec.rb +139 -0
  1487. data/spec/lutaml/xml/schema/xsd/liquid_methods/schema_spec.rb +75 -0
  1488. data/spec/lutaml/xml/schema/xsd/liquid_methods/simple_content_spec.rb +79 -0
  1489. data/spec/lutaml/xml/schema/xsd/namespace_uri_remapping_spec.rb +246 -0
  1490. data/spec/lutaml/xml/schema/xsd/schema_helper_methods_spec.rb +237 -0
  1491. data/spec/lutaml/xml/schema/xsd/schema_mapping_spec.rb +742 -0
  1492. data/spec/lutaml/xml/schema/xsd/schema_validator_spec.rb +228 -0
  1493. data/spec/lutaml/xml/schema/xsd/spec_helper.rb +26 -0
  1494. data/spec/lutaml/xml/schema/xsd/validation_error_spec.rb +189 -0
  1495. data/spec/lutaml/xml/schema/xsd/validation_result_spec.rb +276 -0
  1496. data/spec/lutaml/xml/schema/xsd/xsd_spec.rb +51 -0
  1497. data/spec/lutaml/xml/schema_primer_spec.rb +393 -0
  1498. data/spec/lutaml/xml/serializable_namespace_spec.rb +125 -0
  1499. data/spec/lutaml/xml/transformation/custom_method_wrapper_spec.rb +48 -0
  1500. data/spec/lutaml/xml/transformation_spec.rb +439 -0
  1501. data/spec/lutaml/xml/type_namespace/collector_spec.rb +212 -0
  1502. data/spec/lutaml/xml/type_namespace/planner_spec.rb +270 -0
  1503. data/spec/lutaml/xml/type_namespace_examples_spec.rb +521 -0
  1504. data/spec/lutaml/xml/type_namespace_integration_spec.rb +332 -0
  1505. data/spec/lutaml/xml/type_namespace_prefix_spec.rb +370 -0
  1506. data/spec/lutaml/xml/type_namespace_resolver_spec.rb +0 -0
  1507. data/spec/lutaml/xml/type_namespace_roundtrip_spec.rb +580 -0
  1508. data/spec/lutaml/xml/w3c_types_spec.rb +376 -0
  1509. data/spec/lutaml/{model → xml}/xml_adapter_spec.rb +64 -17
  1510. data/spec/lutaml/xml/xml_declaration_spec.rb +568 -0
  1511. data/spec/lutaml/xml/xml_element_guard_spec.rb +138 -0
  1512. data/spec/lutaml/{model/xml → xml}/xml_element_spec.rb +1 -1
  1513. data/spec/lutaml/xml/xml_lang_spec.rb +441 -0
  1514. data/spec/lutaml/xml/xml_space_spec.rb +247 -0
  1515. data/spec/lutaml/xml/xml_space_type_spec.rb +161 -0
  1516. data/spec/lutaml/xml/xml_spec.rb +122 -0
  1517. data/spec/parent_root_spec.rb +63 -0
  1518. data/spec/person_spec.rb +9 -9
  1519. data/spec/spec_helper.rb +69 -6
  1520. data/spec/support/test_adapter_config.rb +101 -0
  1521. data/spec/support/test_namespaces.rb +185 -0
  1522. data/spec/support/trace_helper.rb +0 -0
  1523. data/spec/support/xml/schema_helper.rb +15 -0
  1524. data/spec/support/xml/xsd/code_example_validator.rb +393 -0
  1525. data/spec/support/xml_mapping_namespaces.rb +176 -0
  1526. metadata +1475 -100
  1527. data/docs/custom_registers.adoc +0 -228
  1528. data/lib/lutaml/model/hash_adapter/mapping.rb +0 -19
  1529. data/lib/lutaml/model/hash_adapter/mapping_rule.rb +0 -9
  1530. data/lib/lutaml/model/hash_adapter/transform.rb +0 -8
  1531. data/lib/lutaml/model/hash_adapter.rb +0 -21
  1532. data/lib/lutaml/model/json/mapping.rb +0 -19
  1533. data/lib/lutaml/model/json/mapping_rule.rb +0 -9
  1534. data/lib/lutaml/model/json/multi_json_adapter.rb +0 -18
  1535. data/lib/lutaml/model/json/standard_adapter.rb +0 -25
  1536. data/lib/lutaml/model/json/transform.rb +0 -8
  1537. data/lib/lutaml/model/jsonl/mapping.rb +0 -19
  1538. data/lib/lutaml/model/jsonl/mapping_rule.rb +0 -9
  1539. data/lib/lutaml/model/jsonl/transform.rb +0 -19
  1540. data/lib/lutaml/model/schema/xsd_schema.rb +0 -62
  1541. data/lib/lutaml/model/toml/mapping_rule.rb +0 -9
  1542. data/lib/lutaml/model/toml/toml_rb_adapter.rb +0 -18
  1543. data/lib/lutaml/model/toml/tomlib_adapter.rb +0 -19
  1544. data/lib/lutaml/model/toml/transform.rb +0 -8
  1545. data/lib/lutaml/model/xml/builder/nokogiri.rb +0 -101
  1546. data/lib/lutaml/model/xml/builder/oga.rb +0 -183
  1547. data/lib/lutaml/model/xml/builder/ox.rb +0 -121
  1548. data/lib/lutaml/model/xml/document.rb +0 -477
  1549. data/lib/lutaml/model/xml/element.rb +0 -32
  1550. data/lib/lutaml/model/xml/mapping.rb +0 -471
  1551. data/lib/lutaml/model/xml/mapping_rule.rb +0 -149
  1552. data/lib/lutaml/model/xml/nokogiri_adapter.rb +0 -234
  1553. data/lib/lutaml/model/xml/oga/document.rb +0 -20
  1554. data/lib/lutaml/model/xml/oga/element.rb +0 -123
  1555. data/lib/lutaml/model/xml/oga_adapter.rb +0 -172
  1556. data/lib/lutaml/model/xml/ox_adapter.rb +0 -229
  1557. data/lib/lutaml/model/xml/transform.rb +0 -8
  1558. data/lib/lutaml/model/xml/xml_attribute.rb +0 -37
  1559. data/lib/lutaml/model/xml/xml_element.rb +0 -167
  1560. data/lib/lutaml/model/xml/xml_namespace.rb +0 -49
  1561. data/lib/lutaml/model/xml.rb +0 -31
  1562. data/lib/lutaml/model/xml_adapter/element.rb +0 -18
  1563. data/lib/lutaml/model/xml_adapter/nokogiri_adapter.rb +0 -15
  1564. data/lib/lutaml/model/xml_adapter/oga_adapter.rb +0 -21
  1565. data/lib/lutaml/model/xml_adapter/ox_adapter.rb +0 -18
  1566. data/lib/lutaml/model/xml_adapter.rb +0 -7
  1567. data/lib/lutaml/model/yaml/mapping.rb +0 -19
  1568. data/lib/lutaml/model/yaml/mapping_rule.rb +0 -9
  1569. data/lib/lutaml/model/yaml/standard_adapter.rb +0 -28
  1570. data/lib/lutaml/model/yaml/transform.rb +0 -8
  1571. data/lib/lutaml/model/yamls/mapping.rb +0 -19
  1572. data/lib/lutaml/model/yamls/mapping_rule.rb +0 -9
  1573. data/lib/lutaml/model/yamls/standard_adapter.rb +0 -34
  1574. data/lib/lutaml/model/yamls/transform.rb +0 -19
  1575. data/spec/benchmarks/xml_parsing_benchmark_spec.rb +0 -74
  1576. data/spec/fixtures/xml/advanced_test_schema.xsd +0 -134
  1577. data/spec/lutaml/model/namespace_spec.rb +0 -57
  1578. data/spec/lutaml/model/xml_adapter/nokogiri_adapter_spec.rb +0 -56
  1579. data/spec/lutaml/model/xml_adapter/oga_adapter_spec.rb +0 -60
  1580. data/spec/lutaml/model/xml_adapter/ox_adapter_spec.rb +0 -61
  1581. data/spec/lutaml/model/xml_adapter/xml_namespace_spec.rb +0 -368
  1582. data/spec/lutaml/model/xml_mapping_rule_spec.rb +0 -158
  1583. data/spec/lutaml/model/xml_mapping_spec.rb +0 -1318
  1584. data/spec/lutaml/model/xml_spec.rb +0 -63
  1585. /data/spec/lutaml/{model/xml → xml}/root_mappings/nested_child_mappings_spec.rb +0 -0
@@ -0,0 +1,1849 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lutaml
4
+ module Xml
5
+ # Phase 2: Declaration Planning
6
+ #
7
+ # Builds ElementNode tree with W3C-compliant attribute prefix decisions.
8
+ # The tree is isomorphic to XmlDataModel for index-based parallel traversal.
9
+ #
10
+ # CRITICAL: This planner ONLY builds trees. NO flat mode.
11
+ #
12
+ class DeclarationPlanner
13
+ # Initialize planner with register for type resolution
14
+ #
15
+ # @param register [Symbol] the register ID for type resolution
16
+ def initialize(register = nil)
17
+ @register = register || Lutaml::Model::Config.default_register
18
+ end
19
+
20
+ # Create declaration plan tree for XmlElement
21
+ #
22
+ # @param root_element [XmlDataModel::XmlElement, Model, nil, Class] root element, model instance, or nil/Class for unit testing
23
+ # @param mapping [Xml::Mapping] the XML mapping
24
+ # @param needs [NamespaceNeeds] namespace needs from collector
25
+ # @param options [Hash] serialization options (may contain :stored_xml_declaration_plan with input_formats)
26
+ # @return [DeclarationPlan] declaration plan with tree structure
27
+ def plan(root_element, mapping, needs, parent_plan: nil, options: {},
28
+ visited_types: Set.new)
29
+ # Normalize root_element: transform Model instances to XmlElement
30
+ root_element = normalize_root_element(root_element, mapping, options)
31
+
32
+ # Allow nil and Class for unit testing (type analysis without element instance)
33
+ if root_element && !root_element.is_a?(Lutaml::Xml::DataModel::XmlElement) && !root_element.is_a?(Class)
34
+ raise ArgumentError,
35
+ "DeclarationPlanner ONLY works with XmlElement trees. Got: #{root_element.class}"
36
+ end
37
+
38
+ # Handle nil or Class root_element for unit testing
39
+ if root_element.nil? || root_element.is_a?(Class)
40
+ # CRITICAL: Resolve type namespace refs BEFORE using type_attribute_namespaces
41
+ TypeNamespaceResolver.new(@register).resolve(needs)
42
+
43
+ # Build namespace_classes hash from needs for unit testing
44
+ namespace_classes = {}
45
+ needs.all_namespace_classes.each do |ns_class|
46
+ namespace_classes[ns_class.uri] = ns_class
47
+ end
48
+
49
+ # CRITICAL: Add namespace_scope namespaces to namespace_classes
50
+ # (even if not used, :always mode requires them to be declared)
51
+ needs.namespace_scope_configs.each do |scope_config|
52
+ ns_class = scope_config.namespace_class
53
+ namespace_classes[ns_class.uri] ||= ns_class
54
+ end
55
+
56
+ # Get element's own namespace (from mapping)
57
+ element_namespace = mapping&.namespace_class
58
+
59
+ # Create minimal root node with namespace hoisting info
60
+ # W3C rule: Namespaces used in attributes MUST use prefix format
61
+ hoisted = {}
62
+
63
+ # FIRST: Process namespace_scope configurations (root-only)
64
+ needs.namespace_scope_configs.each do |scope_config|
65
+ ns_class = scope_config.namespace_class
66
+ next if ns_class == element_namespace # Don't add root's own namespace here
67
+
68
+ # Check :always mode or :auto mode with usage
69
+ ns_usage = needs.namespace(ns_class.to_key)
70
+ should_declare = scope_config.always_mode? ||
71
+ (scope_config.auto_mode? && ns_usage&.used_in&.any?)
72
+
73
+ if should_declare
74
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
75
+ hoisted[prefix] = ns_class.uri
76
+ end
77
+ end
78
+
79
+ # SECOND: Add element's own namespace (if not already added)
80
+ if element_namespace && !hoisted.value?(element_namespace.uri)
81
+ # Check if element's namespace is used in type attributes
82
+ # If so, use prefix format (W3C rule: namespaces in attributes MUST use prefix)
83
+ element_ns_in_attributes = needs.type_attribute_namespaces.any? do |ns|
84
+ ns.uri == element_namespace.uri
85
+ end
86
+
87
+ # Check use_prefix option (Tier 1 priority)
88
+ use_prefix_option = options[:use_prefix]
89
+
90
+ if element_ns_in_attributes
91
+ # Namespace used in attributes - MUST use prefix format
92
+ prefix = element_namespace.prefix_default || "ns#{hoisted.keys.length}"
93
+ hoisted[prefix] = element_namespace.uri
94
+ elsif use_prefix_option == true
95
+ # Force prefix format when use_prefix: true
96
+ prefix = element_namespace.prefix_default || "ns#{hoisted.keys.length}"
97
+ hoisted[prefix] = element_namespace.uri
98
+ elsif use_prefix_option.is_a?(String)
99
+ # Use custom prefix string
100
+ hoisted[use_prefix_option] = element_namespace.uri
101
+ elsif use_prefix_option == false
102
+ # Force default format when use_prefix: false
103
+ hoisted[nil] = element_namespace.uri
104
+ elsif element_namespace.element_form_default_set? &&
105
+ element_namespace.element_form_default == :unqualified
106
+ # W3C elementFormDefault="unqualified": local elements should be unqualified.
107
+ # When parent uses prefix format, children can simply omit xmlns (blank namespace).
108
+ # When parent uses default format, children need xmlns="" to opt out.
109
+ # Prefer prefix format so children can be truly blank (no xmlns attribute).
110
+ # CRITICAL: Only applies when explicitly set, not when defaulted to :unqualified.
111
+ prefix = element_namespace.prefix_default || "ns#{hoisted.keys.length}"
112
+ hoisted[prefix] = element_namespace.uri
113
+ else
114
+ # Default: prefer default format (cleaner)
115
+ hoisted[nil] = element_namespace.uri
116
+ end
117
+ end
118
+
119
+ # THIRD: Add type namespaces (W3C: type namespaces MUST use prefix)
120
+ # CRITICAL: Type namespaces respect namespace_scope directive.
121
+ # When namespace_scope is configured, only hoist type namespaces in scope.
122
+ #
123
+ # Check if namespace_scope is configured
124
+ has_namespace_scope = !needs.namespace_scope_configs.empty?
125
+
126
+ # Type attribute namespaces
127
+ needs.type_attribute_namespaces.each do |ns_class|
128
+ ns_uri = ns_class.uri
129
+ next if hoisted.value?(ns_uri) # Skip if already added
130
+
131
+ # If namespace_scope is configured, only hoist if in scope
132
+ if has_namespace_scope
133
+ scope_config = needs.scope_config_for(ns_class)
134
+ next unless scope_config
135
+ end
136
+
137
+ # Namespaces in attributes MUST use prefix format (W3C rule)
138
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
139
+ hoisted[prefix] = ns_class.uri
140
+ end
141
+
142
+ # Type element namespaces
143
+ needs.type_element_namespaces.each do |ns_class|
144
+ ns_uri = ns_class.uri
145
+ next if hoisted.value?(ns_uri) # Skip if already added
146
+ next if ns_class == element_namespace # Skip element's own namespace
147
+
148
+ # NOTE: Type namespaces are different from child element namespaces.
149
+ # Type namespaces are declared on Type::Value subclasses and used as
150
+ # prefixes on child elements. They MUST be hoisted to root with prefix
151
+ # format (W3C constraint: only one default namespace per element).
152
+ #
153
+ # The condition below only applies to child element namespaces, NOT Type
154
+ # namespaces. Type namespaces should ALWAYS be hoisted.
155
+ #
156
+ # Examples of child element namespaces (should NOT be hoisted if different):
157
+ # - Root has XMI namespace, child has XMI_NEW namespace → child declares
158
+ # - Root has NO namespace, child has XMI namespace → child declares
159
+ #
160
+ # Examples of Type namespaces (should ALWAYS be hoisted):
161
+ # - Root has any namespace, attribute type has XMI namespace → hoist XMI
162
+ # - Root has NO namespace, attribute type has XMI namespace → hoist XMI
163
+ # Type namespaces are NOT about element structure, they're about type identity.
164
+
165
+ # If namespace_scope is configured, only hoist if in scope
166
+ if has_namespace_scope
167
+ scope_config = needs.scope_config_for(ns_class)
168
+ next unless scope_config
169
+ end
170
+
171
+ # Type element namespaces MUST use prefix format
172
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
173
+ hoisted[prefix] = ns_class.uri
174
+ end
175
+
176
+ # FOURTH: Add remaining namespaces not in namespace_scope
177
+ needs.all_namespace_classes.each do |ns_class|
178
+ ns_uri = ns_class.uri
179
+ next if hoisted.value?(ns_uri) # Skip if already added
180
+
181
+ # Check if this namespace is in namespace_scope (skip if yes)
182
+ scope_config = needs.scope_config_for(ns_class)
183
+ next if scope_config
184
+
185
+ # Add remaining namespace (default format preferred)
186
+ hoisted[nil] = ns_class.uri
187
+ end
188
+
189
+ root_node = DeclarationPlan::ElementNode.new(
190
+ qualified_name: "",
191
+ use_prefix: nil,
192
+ hoisted_declarations: hoisted,
193
+ )
194
+
195
+ # Build children_plans for attributes with Serializable types
196
+ children_plans = build_children_plans_from_metadata(mapping, needs,
197
+ options)
198
+
199
+ return DeclarationPlan.new(
200
+ root_node: root_node,
201
+ global_prefix_registry: build_prefix_registry(needs),
202
+ input_formats: {},
203
+ namespace_classes: namespace_classes,
204
+ children_plans: children_plans,
205
+ original_namespace_uris: options[:__original_namespace_uris] || {},
206
+ )
207
+ end
208
+
209
+ # TREE PATH: XmlElement tree path
210
+ # CRITICAL: Resolve type namespace refs BEFORE using type_attribute_namespaces
211
+ TypeNamespaceResolver.new(@register).resolve(needs)
212
+
213
+ # Extract input_formats from stored plan if present (format preservation)
214
+ input_formats = options[:stored_xml_declaration_plan]&.input_formats || {}
215
+ build_options = options.merge(input_formats: input_formats)
216
+
217
+ # Build namespace_classes hash for unit testing compatibility
218
+ namespace_classes = {}
219
+ needs.all_namespace_classes.each do |ns_class|
220
+ namespace_classes[ns_class.uri] = ns_class
221
+ end
222
+
223
+ # Build the element node tree recursively (mark root, no parent context)
224
+ root_node = build_element_node(
225
+ root_element, mapping, needs, build_options,
226
+ is_root: true,
227
+ parent_format: nil,
228
+ parent_namespace_class: nil,
229
+ parent_namespace_prefix: nil,
230
+ parent_hoisted: {}
231
+ )
232
+
233
+ # Build children_plans for each child element (for child_plan() method)
234
+ children_plans = build_children_plans(root_element, mapping, needs,
235
+ build_options)
236
+
237
+ # Create DeclarationPlan with tree and input_formats
238
+ DeclarationPlan.new(
239
+ root_node: root_node,
240
+ global_prefix_registry: build_prefix_registry(needs),
241
+ input_formats: input_formats,
242
+ namespace_classes: namespace_classes,
243
+ children_plans: children_plans,
244
+ original_namespace_uris: options[:__original_namespace_uris] || {},
245
+ )
246
+ end
247
+
248
+ # Create declaration plan for a collection
249
+ #
250
+ # @param collection [Collection] the collection object
251
+ # @param mapping [Xml::Mapping] the XML mapping
252
+ # @param needs [NamespaceNeeds] namespace needs from collector
253
+ # @return [DeclarationPlan] declaration plan with children_plans
254
+ def plan_collection(collection, mapping, needs)
255
+ # For collections, create a plan with children_plans for each item
256
+ root_node = DeclarationPlan::ElementNode.new(
257
+ qualified_name: mapping.root_element || "",
258
+ use_prefix: nil,
259
+ hoisted_declarations: {},
260
+ )
261
+
262
+ # Build namespace_classes from needs
263
+ namespace_classes = {}
264
+ needs.all_namespace_classes.each do |ns_class|
265
+ namespace_classes[ns_class.uri] = ns_class
266
+ end
267
+
268
+ # Build individual child plans for collection items
269
+ children_plans = build_collection_item_plans(collection, mapping, needs)
270
+
271
+ DeclarationPlan.new(
272
+ root_node: root_node,
273
+ global_prefix_registry: build_prefix_registry(needs),
274
+ input_formats: {},
275
+ namespace_classes: namespace_classes,
276
+ children_plans: children_plans,
277
+ )
278
+ end
279
+
280
+ private
281
+
282
+ attr_reader :register
283
+
284
+ # Resolve the correct register for a child mapper class
285
+ #
286
+ # @param mapper_class [Class] The child's mapper class
287
+ # @return [Symbol] The resolved register ID
288
+ def register_for(mapper_class)
289
+ Lutaml::Model::Register.resolve_for_child(mapper_class, @register)
290
+ end
291
+
292
+ # Build individual child plans for collection items
293
+ #
294
+ # @param collection [Collection] the collection object
295
+ # @param mapping [Xml::Mapping] the XML mapping
296
+ # @param needs [NamespaceNeeds] namespace needs from collector
297
+ # @return [Hash<Integer, DeclarationPlan>] Children plans by item index
298
+ def build_collection_item_plans(collection, _mapping, _needs)
299
+ children_plans = {}
300
+
301
+ return children_plans unless collection.respond_to?(:each)
302
+
303
+ # Get the item type from the collection class
304
+ item_type = begin
305
+ collection.class.instance_type
306
+ rescue StandardError
307
+ nil
308
+ end
309
+
310
+ collection.each_with_index do |item, index|
311
+ next unless item
312
+
313
+ # Get the item's mapper class
314
+ item_mapper_class = if item.is_a?(Lutaml::Model::Serializable)
315
+ item.class
316
+ elsif item_type.is_a?(Class)
317
+ item_type
318
+ else
319
+ next
320
+ end
321
+
322
+ # Get the item's XML mapping
323
+ item_reg = register_for(item_mapper_class)
324
+ item_mapping = item_mapper_class.mappings_for(:xml, item_reg)
325
+ next unless item_mapping
326
+
327
+ # Collect namespace needs for this item
328
+ collector = NamespaceCollector.new(item_reg)
329
+ item_needs = collector.collect(item, item_mapping)
330
+
331
+ # Build a plan for this item
332
+ item_plan = plan(item, item_mapping, item_needs)
333
+ children_plans[index] = item_plan if item_plan
334
+ end
335
+
336
+ children_plans
337
+ end
338
+
339
+ # Normalize root element: transform Model instances to XmlElement
340
+ #
341
+ # @param root_element [XmlDataModel::XmlElement, Model, nil, Class] Root element
342
+ # @param mapping [Xml::Mapping] XML mapping
343
+ # @param options [Hash] Serialization options
344
+ # @return [XmlDataModel::XmlElement, nil, Class] Normalized root element
345
+ def normalize_root_element(root_element, _mapping, options)
346
+ return root_element if root_element.nil? || root_element.is_a?(Class)
347
+ return root_element if root_element.is_a?(Lutaml::Xml::DataModel::XmlElement)
348
+
349
+ # Check if root_element is a Model instance (has xml mapping)
350
+ if root_element.is_a?(Lutaml::Model::Serialize)
351
+ # Get mapper_class from options or infer from root_element
352
+ mapper_class = options[:mapper_class] || root_element.class
353
+
354
+ # Get mapping for the model class
355
+ root_reg = register_for(mapper_class)
356
+ mapping_dsl = mapper_class.mappings_for(:xml, root_reg)
357
+
358
+ # Use Xml::Transformation to convert model to XmlElement
359
+ # Pass register ID directly (Transformation handles Symbol)
360
+ transformation = Xml::Transformation.new(mapper_class, mapping_dsl,
361
+ :xml, root_reg)
362
+ transformed = transformation.transform(root_element, options)
363
+
364
+ # Return transformed XmlElement
365
+ return transformed if transformed.is_a?(Lutaml::Xml::DataModel::XmlElement)
366
+ end
367
+
368
+ # Return as-is if no transformation needed
369
+ root_element
370
+ end
371
+
372
+ # Build children_plans hash for child_plan() method
373
+ #
374
+ # @param xml_element [XmlDataModel::XmlElement] Parent element
375
+ # @param mapping [Xml::Mapping] XML mapping
376
+ # @param needs [NamespaceNeeds] Namespace needs
377
+ # @param options [Hash] Serialization options
378
+ # @return [Hash<Symbol, DeclarationPlan>] Children plans by attribute name
379
+ def build_children_plans(xml_element, mapping, needs, options)
380
+ children_plans = {}
381
+
382
+ # Get mapper_class to find child attributes
383
+ mapper_class = options[:mapper_class]
384
+ return children_plans unless mapper_class.is_a?(Class) &&
385
+ mapper_class.include?(Lutaml::Model::Serialize)
386
+
387
+ # Build namespace_classes hash for child plans
388
+ namespace_classes = {}
389
+ needs.all_namespace_classes.each do |ns_class|
390
+ namespace_classes[ns_class.uri] = ns_class
391
+ end
392
+
393
+ # Iterate through XmlElement children
394
+ xml_element.children.each do |xml_child|
395
+ next unless xml_child.is_a?(Lutaml::Xml::DataModel::XmlElement)
396
+
397
+ # Find the matching mapping rule for this child
398
+ child_name = xml_child.name
399
+ matching_rule = mapping.elements.find do |rule|
400
+ rule.name.to_s == child_name
401
+ end
402
+ next unless matching_rule
403
+
404
+ # Get the attribute definition for this child
405
+ attr_def = mapper_class.attributes[matching_rule.to]
406
+ next unless attr_def
407
+
408
+ # Build child's hoisted declarations
409
+ # CRITICAL: Child elements with type namespace attributes need those
410
+ # namespaces declared on themselves. Get type attribute namespaces from
411
+ # child's own needs (stored in needs.children)
412
+ child_hoisted = build_child_hoisted_declarations(attr_def, needs,
413
+ options,
414
+ mapper_class: mapper_class)
415
+
416
+ # Create child DeclarationPlan with the child's namespace info
417
+ # Children inherit parent's namespace_classes
418
+ child_plan = DeclarationPlan.new(
419
+ root_node: DeclarationPlan::ElementNode.new(
420
+ qualified_name: xml_child.name,
421
+ use_prefix: nil,
422
+ hoisted_declarations: child_hoisted,
423
+ ),
424
+ global_prefix_registry: build_prefix_registry(needs),
425
+ input_formats: {},
426
+ namespace_classes: namespace_classes,
427
+ )
428
+
429
+ # Store by attribute name
430
+ children_plans[attr_def.name] = child_plan
431
+ end
432
+
433
+ children_plans
434
+ end
435
+
436
+ # Build children_plans from mapper metadata (for nil/Class root_element)
437
+ #
438
+ # @param mapping [Xml::Mapping] XML mapping
439
+ # @param needs [NamespaceNeeds] Namespace needs
440
+ # @param options [Hash] Serialization options
441
+ # @return [Hash<Symbol, DeclarationPlan>] Children plans by attribute name
442
+ def build_children_plans_from_metadata(mapping, needs, options)
443
+ children_plans = {}
444
+
445
+ # Get mapper_class to find child attributes
446
+ mapper_class = options[:mapper_class]
447
+ return children_plans unless mapper_class.is_a?(Class) &&
448
+ mapper_class.include?(Lutaml::Model::Serialize)
449
+
450
+ # Build namespace_classes hash for child plans
451
+ namespace_classes = {}
452
+ needs.all_namespace_classes.each do |ns_class|
453
+ namespace_classes[ns_class.uri] = ns_class
454
+ end
455
+
456
+ # Get parent's hoisted declarations for child inheritance
457
+ parent_hoisted = build_parent_hoisted_for_children(mapping, needs,
458
+ options)
459
+
460
+ # Iterate through mapper_class attributes
461
+ mapper_class.attributes.each_value do |attr_def|
462
+ # Check if attribute has a Serializable type
463
+ attr_type = attr_def.type(register_for(mapper_class))
464
+ next unless attr_type
465
+ next unless attr_type.is_a?(Class)
466
+ next unless attr_type < Lutaml::Model::Serialize
467
+
468
+ # Create child DeclarationPlan with parent's namespace_classes
469
+ # Child inherits parent's hoisted declarations
470
+ child_plan = DeclarationPlan.new(
471
+ root_node: DeclarationPlan::ElementNode.new(
472
+ qualified_name: "",
473
+ use_prefix: nil,
474
+ hoisted_declarations: parent_hoisted,
475
+ ),
476
+ global_prefix_registry: build_prefix_registry(needs),
477
+ input_formats: {},
478
+ namespace_classes: namespace_classes,
479
+ )
480
+
481
+ # Store by attribute name
482
+ children_plans[attr_def.name] = child_plan
483
+ end
484
+
485
+ children_plans
486
+ end
487
+
488
+ # Build parent's hoisted declarations for child inheritance
489
+ #
490
+ # @param mapping [Xml::Mapping] XML mapping
491
+ # @param needs [NamespaceNeeds] Namespace needs
492
+ # @param options [Hash] Serialization options
493
+ # @return [Hash<String|nil, String>] Hoisted declarations {prefix => uri}
494
+ def build_parent_hoisted_for_children(mapping, needs, options)
495
+ hoisted = {}
496
+
497
+ # Get element's own namespace (from mapping's namespace_class)
498
+ element_namespace = mapping&.namespace_class
499
+
500
+ # Process namespace_scope configurations
501
+ needs.namespace_scope_configs.each do |scope_config|
502
+ ns_class = scope_config.namespace_class
503
+ next if ns_class == element_namespace
504
+
505
+ ns_usage = needs.namespace(ns_class.to_key)
506
+ should_declare = scope_config.always_mode? ||
507
+ (scope_config.auto_mode? && ns_usage&.used_in&.any?)
508
+
509
+ if should_declare
510
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
511
+ hoisted[prefix] = ns_class.uri
512
+ end
513
+ end
514
+
515
+ # Add element's own namespace (if not already added)
516
+ if element_namespace && !hoisted.value?(element_namespace.uri)
517
+ use_prefix_option = options[:use_prefix]
518
+
519
+ case use_prefix_option
520
+ when true
521
+ prefix = element_namespace.prefix_default || "ns#{hoisted.keys.length}"
522
+ hoisted[prefix] = element_namespace.uri
523
+ when String
524
+ hoisted[use_prefix_option] = element_namespace.uri
525
+ when false
526
+ hoisted[nil] = element_namespace.uri
527
+ else
528
+ # Default: prefer default format (cleaner)
529
+ hoisted[nil] = element_namespace.uri
530
+ end
531
+ end
532
+
533
+ # Add type namespaces
534
+ # Type attribute namespaces
535
+ needs.type_attribute_namespaces.each do |ns_class|
536
+ ns_uri = ns_class.uri
537
+ next if hoisted.value?(ns_uri)
538
+
539
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
540
+ hoisted[prefix] = ns_class.uri
541
+ end
542
+
543
+ # Type element namespaces
544
+ needs.type_element_namespaces.each do |ns_class|
545
+ ns_uri = ns_class.uri
546
+ next if hoisted.value?(ns_uri)
547
+
548
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
549
+ hoisted[prefix] = ns_class.uri
550
+ end
551
+
552
+ # Add remaining namespaces
553
+ needs.all_namespace_classes.each do |ns_class|
554
+ ns_uri = ns_class.uri
555
+ next if hoisted.value?(ns_uri)
556
+
557
+ scope_config = needs.scope_config_for(ns_class)
558
+ next if scope_config
559
+
560
+ hoisted[nil] = ns_class.uri
561
+ end
562
+
563
+ hoisted
564
+ end
565
+
566
+ # Build hoisted declarations for a child element
567
+ #
568
+ # When a child element has attributes with type namespaces, those namespaces
569
+ # must be declared on the child element itself (W3C compliance).
570
+ #
571
+ # @param attr_def [Attribute] The attribute definition for the child
572
+ # @param needs [NamespaceNeeds] Namespace needs
573
+ # @param options [Hash] Serialization options
574
+ # @return [Hash<String|nil, String>] Hoisted declarations {prefix => uri}
575
+ def build_child_hoisted_declarations(attr_def, needs, _options,
576
+ mapper_class: nil)
577
+ hoisted = {}
578
+
579
+ # Get the child's own namespace needs
580
+ child_needs = needs.child(attr_def.name)
581
+ return hoisted unless child_needs
582
+
583
+ # Add type attribute namespaces for the child element
584
+ # CRITICAL: Type attribute namespaces MUST use prefix format (W3C rule)
585
+ # NOTE: We only add type ATTRIBUTE namespaces, not type ELEMENT namespaces.
586
+ # Type element namespaces are used by child elements and should be declared
587
+ # on the parent element (or root, depending on namespace_scope).
588
+ child_needs.type_attribute_namespaces.each do |ns_class|
589
+ ns_uri = ns_class.uri
590
+ next if hoisted.value?(ns_uri)
591
+
592
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
593
+ hoisted[prefix] = ns_class.uri
594
+ end
595
+
596
+ # Get child's element namespace if available
597
+ child_type = attr_def.type(mapper_class ? register_for(mapper_class) : @register)
598
+ if child_type.respond_to?(:<) && child_type < Lutaml::Model::Serialize
599
+ child_reg = register_for(child_type)
600
+ child_mapping = child_type.mappings_for(:xml, child_reg)
601
+ if child_mapping&.namespace_class
602
+ element_namespace = child_mapping.namespace_class
603
+ # Only add if not already present
604
+ unless hoisted.value?(element_namespace.uri)
605
+ # For child elements, prefer default format (cleaner)
606
+ hoisted[nil] = element_namespace.uri
607
+ end
608
+ end
609
+ end
610
+
611
+ hoisted
612
+ end
613
+
614
+ # Build ElementNode for an XmlElement (recursive)
615
+ #
616
+ # @param xml_element [XmlDataModel::XmlElement] Element to plan
617
+ # @param mapping [Xml::Mapping] XML mapping
618
+ # @param needs [NamespaceNeeds] Namespace needs
619
+ # @param options [Hash] Serialization options (may contain :input_formats)
620
+ # @param parent_node [ElementNode, nil] Parent element node
621
+ # @param is_root [Boolean] Whether this is the root element
622
+ # @param parent_format [Symbol, nil] Parent's namespace format (:default or :prefix)
623
+ # @param parent_namespace_class [Class, nil] Parent's namespace class
624
+ # @param parent_namespace_prefix [String, nil] Parent's actual namespace prefix
625
+ # @param parent_hoisted [Hash] Namespaces hoisted on parent {prefix => uri}
626
+ # @return [ElementNode] Element node with all decisions
627
+ def build_element_node(xml_element, mapping, needs, options,
628
+ parent_node: nil, is_root: false, parent_format: nil, parent_namespace_class: nil, parent_namespace_prefix: nil, parent_hoisted: {}, element_path: [])
629
+ # Determine element's prefix (checks input_formats, parent context for preservation)
630
+ # Priority:
631
+ # 1. Lutaml::Xml::XmlElement (from parsed XML): has namespace_prefix_explicit
632
+ # 2. DataModel::XmlElement (from serialization): has @__xml_namespace_prefix
633
+ element_prefix_explicit = xml_element.is_a?(Lutaml::Xml::XmlElement) &&
634
+ xml_element.namespace_prefix_explicit
635
+ # For ROOT elements: don't use @__xml_namespace_prefix from XmlElement.
636
+ # The root's prefix should be determined by the DecisionEngine (model's prefix_default).
637
+ # This ensures mixed content roots use their namespace's default prefix, not the input prefix.
638
+ # For NESTED elements: use @__xml_namespace_prefix if set (supports doubly-defined namespaces).
639
+ element_used_prefix = if is_root
640
+ nil
641
+ elsif xml_element.is_a?(Lutaml::Xml::XmlElement)
642
+ xml_element.namespace_prefix
643
+ else
644
+ xml_element.xml_namespace_prefix
645
+ end
646
+
647
+ element_prefix = determine_element_prefix(
648
+ xml_element, mapping, needs, options,
649
+ is_root: is_root,
650
+ parent_format: parent_format,
651
+ parent_namespace_class: parent_namespace_class,
652
+ parent_namespace_prefix: parent_namespace_prefix,
653
+ parent_hoisted: parent_hoisted,
654
+ element_prefix_explicit: element_prefix_explicit,
655
+ element_used_prefix: element_used_prefix
656
+ )
657
+
658
+ # Determine hoisted xmlns declarations at this element
659
+ # CRITICAL: Pass element_prefix to avoid calling determine_element_prefix twice
660
+ # which could return different results due to context differences
661
+ hoisted = determine_hoisted_declarations(xml_element, mapping, needs,
662
+ options, is_root: is_root, parent_hoisted: parent_hoisted, element_prefix: element_prefix, element_path: element_path, parent_namespace_class: parent_namespace_class, parent_namespace_prefix: parent_namespace_prefix)
663
+
664
+ # For ROOT element with a stored input plan, merge additional declarations
665
+ # from the stored plan that the normal computation didn't include.
666
+ # This preserves namespace prefix declarations from input XML that
667
+ # the recomputation would not produce. Specifically:
668
+ # - Doubly-defined: xmlns="..." AND xmlns:b="..." on the same element
669
+ # - Non-default prefix: xmlns:xyzabc="..." when model uses prefix_default "a:"
670
+ #
671
+ # Only merge when the root element itself did NOT use a prefix in the input.
672
+ # When the root's element name had a prefix (e.g., <examplecom:schema>),
673
+ # the deserialization sets @__xml_namespace_prefix on the root XmlElement,
674
+ # and element_builder clears child prefixes — so the stored plan's
675
+ # prefix declarations are NOT needed by any child element.
676
+ if is_root && !options.key?(:use_prefix)
677
+ stored_plan = options[:stored_xml_declaration_plan]
678
+ if stored_plan.respond_to?(:root_node) && stored_plan.root_node.respond_to?(:hoisted_declarations)
679
+ root_has_input_prefix = xml_element.xml_namespace_prefix.to_s != ""
680
+
681
+ unless root_has_input_prefix
682
+ stored_hoisted = stored_plan.root_node.hoisted_declarations
683
+ stored_original_uris = stored_plan.original_namespace_uris || {}
684
+
685
+ stored_hoisted.each do |prefix, uri|
686
+ effective_uri = stored_original_uris[uri] || uri
687
+ already_present = hoisted.any? do |_k, v|
688
+ v == effective_uri || v == uri
689
+ end
690
+ if already_present && !hoisted.key?(prefix)
691
+ hoisted[prefix] = uri
692
+ end
693
+ end
694
+ end
695
+ end
696
+ end
697
+ # Determine if child needs xmlns="" (W3C compliance)
698
+ # W3C XML Namespaces 1.0 §6.2: When parent has default namespace and child
699
+ # has NO namespace (namespace_class is nil), child MUST explicitly opt out
700
+ # with xmlns="" to prevent inheriting parent's default namespace.
701
+ #
702
+ # This applies when:
703
+ # 1. Transformation marked the element as needing xmlns="" (explicit :blank)
704
+ # 2. OR element has no namespace AND parent uses default format AND the default
705
+ # namespace does NOT have element_form_default :qualified
706
+ #
707
+ # Note: The transformation sets @needs_xmlns_blank on the XmlElement when the child
708
+ # model has explicit `namespace :blank` declaration.
709
+ element_marked_blank = xml_element.respond_to?(:needs_xmlns_blank) && xml_element.needs_xmlns_blank
710
+
711
+ # Add xmlns="" when parent's effective namespace form is :qualified.
712
+ # This implements the W3C XML Schema default behavior:
713
+ # - element_form_default :qualified (explicit) → children with no namespace get xmlns=""
714
+ # to opt out of parent's default namespace
715
+ # - element_form_default :unqualified (explicit) → children inherit parent's ns, no xmlns=""
716
+ # - not set (nil) → W3C default is :qualified, BUT children opt out when parent's
717
+ # namespace doesn't have an explicit form set (nested conflict case)
718
+ #
719
+ # The parent's effective namespace form (default_ns_form) is:
720
+ # - nil when no form was explicitly set on the parent's namespace
721
+ # - :qualified when explicitly set to qualified
722
+ # - :unqualified when explicitly set to unqualified
723
+ default_ns_form = options[:default_ns_element_form_default]
724
+ parent_ns_class = parent_namespace_class
725
+
726
+ # Skip xmlns="" when parent explicitly set :unqualified.
727
+ # Override original default_ns_form.nil? with parent_explicitly_unqualified check.
728
+ parent_explicitly_unqualified = parent_ns_class&.element_form_default_set? &&
729
+ parent_ns_class.element_form_default == :unqualified
730
+
731
+ # Original: default_ns_form.nil? (W3C default is :qualified, opt out with xmlns="")
732
+ # Override: if parent explicitly set :unqualified, don't opt out (inherit parent's ns)
733
+ implicit_blank_needs_xmlns = xml_element.namespace_class.nil? &&
734
+ parent_hoisted&.key?(nil) &&
735
+ default_ns_form.nil? && !parent_explicitly_unqualified
736
+
737
+ child_needs_xmlns_blank = element_marked_blank || implicit_blank_needs_xmlns
738
+
739
+ # Build schema_location_attr if root element and any namespace has schema_location
740
+ schema_location_attr = nil
741
+ if is_root
742
+ schema_location_attr = build_schema_location_attr_for_needs(needs)
743
+ end
744
+
745
+ # Create ElementNode
746
+ element_node = DeclarationPlan::ElementNode.new(
747
+ qualified_name: build_qualified_element_name(xml_element,
748
+ element_prefix),
749
+ use_prefix: element_prefix,
750
+ hoisted_declarations: hoisted,
751
+ needs_xmlns_blank: child_needs_xmlns_blank,
752
+ schema_location_attr: schema_location_attr,
753
+ )
754
+
755
+ # Calculate this element's format for passing to children
756
+ this_format = element_prefix.nil? ? :default : :prefix
757
+ this_namespace = xml_element.namespace_class
758
+
759
+ # Get this element's element_form_default for passing to children
760
+ # This determines whether child elements inherit this element's namespace
761
+ this_element_form_default = this_namespace&.element_form_default
762
+
763
+ # Track the effective default namespace's element_form_default
764
+ # This is used to determine if children should inherit the default namespace
765
+ # If this element declares a default namespace (hoisted[nil]), use its element_form_default
766
+ # ONLY if it was explicitly set. Otherwise use the parent's effective value.
767
+ effective_default_ns_form = if hoisted.key?(nil) && this_namespace&.element_form_default_set?
768
+ this_namespace.element_form_default
769
+ else
770
+ options[:default_ns_element_form_default]
771
+ end
772
+
773
+ # Plan ALL attributes (PRESERVES ORDER)
774
+ xml_element.attributes.each do |xml_attr|
775
+ attr_node = plan_attribute(xml_attr, xml_element, mapping, options)
776
+ element_node.add_attribute_node(attr_node)
777
+ end
778
+
779
+ # Get mapper_class from options to match children to mapping rules
780
+ mapper_class = options[:mapper_class]
781
+ attributes = if mapper_class.is_a?(Class) && mapper_class.include?(Lutaml::Model::Serialize)
782
+ mapper_class.attributes
783
+ else
784
+ {}
785
+ end
786
+
787
+ # Recursively plan ALL children (PRESERVES ORDER, mark as NOT root, pass parent context)
788
+ xml_element.children.each do |xml_child|
789
+ next unless xml_child.is_a?(Lutaml::Xml::DataModel::XmlElement)
790
+
791
+ # Match child XmlElement to its mapping rule to get correct child mapping
792
+ child_name = xml_child.name
793
+ matching_rule = mapping.elements.find do |rule|
794
+ rule.name.to_s == child_name
795
+ end
796
+
797
+ child_mapping = mapping # Default to parent mapping
798
+ child_options = options
799
+
800
+ if matching_rule && attributes.any?
801
+ # Get child's mapper_class and mapping
802
+ attr_def = attributes[matching_rule.to]
803
+ if attr_def
804
+ child_reg = mapper_class ? register_for(mapper_class) : @register
805
+ child_type = attr_def.type(child_reg)
806
+ if child_type.respond_to?(:<) && child_type < Lutaml::Model::Serialize
807
+ child_type_reg = register_for(child_type)
808
+ child_mapping_obj = child_type.mappings_for(:xml,
809
+ child_type_reg)
810
+ if child_mapping_obj
811
+ child_mapping = child_mapping_obj
812
+ # CRITICAL: Pass parent's mapping so child can find its attribute name
813
+ # NOTE: do NOT propagate use_prefix to child elements
814
+ # use_prefix only applies to root element, not to children
815
+ # Children should use their own namespace's default presentation
816
+ use_prefix_value = options[:use_prefix]
817
+ base_child_options = {
818
+ mapper_class: child_type,
819
+ parent_mapping: mapping,
820
+ parent_element_form_default: this_element_form_default,
821
+ default_ns_element_form_default: effective_default_ns_form,
822
+ }
823
+ if use_prefix_value == true
824
+ # Do NOT propagate use_prefix: true to children
825
+ # Children should use their own namespace's default presentation
826
+ elsif use_prefix_value.is_a?(String)
827
+ # Custom string prefix is specific to root's namespace - don't propagate
828
+ else
829
+ # use_prefix: false or nil - don't propagate
830
+ end
831
+ child_options = options.except(:use_prefix).merge(base_child_options)
832
+ end
833
+ end
834
+ end
835
+ end
836
+
837
+ child_node = build_element_node(
838
+ xml_child, child_mapping, needs, child_options,
839
+ parent_node: element_node,
840
+ is_root: false,
841
+ parent_format: this_format,
842
+ parent_namespace_class: this_namespace,
843
+ parent_namespace_prefix: element_prefix,
844
+ parent_hoisted: parent_hoisted.merge(hoisted),
845
+ element_path: element_path + [xml_child.name]
846
+ )
847
+ element_node.add_element_node(child_node)
848
+ end
849
+
850
+ element_node
851
+ end
852
+
853
+ # Plan attribute prefix using W3C attributeFormDefault semantics
854
+ #
855
+ # W3C Rules (MECE):
856
+ # 1. Same namespace + unqualified → NO prefix
857
+ # 2. Different namespace OR qualified → YES prefix
858
+ # 3. Only attribute has namespace → YES prefix
859
+ # 4. No namespace but qualified → inherit element prefix
860
+ # 5. No namespace, unqualified → NO prefix (W3C default)
861
+ #
862
+ # @param xml_attr [XmlDataModel::XmlAttribute] Attribute to plan
863
+ # @param xml_element [XmlDataModel::XmlElement] Parent element
864
+ # @param mapping [Xml::Mapping] XML mapping
865
+ # @param options [Hash] Serialization options
866
+ # @return [AttributeNode] Attribute decision node
867
+ def plan_attribute(xml_attr, xml_element, mapping, options)
868
+ attr_ns_class = xml_attr.namespace_class
869
+ element_ns_class = xml_element.namespace_class
870
+
871
+ # Get W3C attributeFormDefault setting
872
+ attribute_form_default = element_ns_class&.attribute_form_default || :unqualified
873
+
874
+ # Compare by URI since namespace classes can be different instances
875
+ # with the same URI (e.g., dynamically created in tests with Class.new)
876
+ same_namespace = attr_ns_class && element_ns_class &&
877
+ attr_ns_class.uri == element_ns_class.uri
878
+
879
+ # Get the attribute's mapping rule to check form option
880
+ mapper_class = options[:mapper_class]
881
+ attr_mapping_rule = nil
882
+ if mapper_class.is_a?(Class) && mapper_class.include?(Lutaml::Model::Serialize)
883
+ attrs = mapper_class.attributes
884
+ attr_def = attrs[xml_attr.name.to_sym] || attrs[xml_attr.name.to_s]
885
+ if attr_def
886
+ attr_mapping_rule = mapping.attributes.find do |r|
887
+ r.to == attr_def.name
888
+ end
889
+ end
890
+ end
891
+
892
+ # W3C Attribute Prefix Decision (MECE)
893
+ # Priority: form option on mapping > same_namespace + attribute_form_default > type namespace
894
+ use_prefix = if attr_mapping_rule&.form == :qualified
895
+ # Priority 1: Explicit form: :qualified → YES prefix
896
+ attr_ns_class&.prefix_default || element_ns_class&.prefix_default
897
+ elsif same_namespace && attribute_form_default == :unqualified
898
+ # Priority 2: Same namespace + unqualified → NO prefix
899
+ nil
900
+ elsif attr_ns_class && element_ns_class
901
+ # Priority 3: Different namespace OR qualified → YES prefix
902
+ attr_ns_class.prefix_default
903
+ elsif attr_ns_class
904
+ # Priority 4: Only attribute has namespace → YES prefix
905
+ attr_ns_class.prefix_default
906
+ elsif attribute_form_default == :qualified
907
+ # Priority 5: No namespace but qualified → inherit element prefix
908
+ # CRITICAL: xmlns declarations (xmlns, xmlns:*) must NEVER have a prefix.
909
+ # The "xmlns" part is part of the declaration syntax, not a namespace prefix.
910
+ # These declarations are handled separately by the XML processor.
911
+ # Also, xsi:* attributes (xsi:schemaLocation, xsi:type, xsi:nil) must
912
+ # ALWAYS use the "xsi" prefix. They should never inherit element prefix.
913
+ # They conventionally belong to the XSI namespace.
914
+ attr_name = xml_attr.name.to_s
915
+ if attr_name.start_with?("xmlns", "xsi:", "xml:")
916
+ nil
917
+ else
918
+ element_ns_class&.prefix_default
919
+ end
920
+ else
921
+ # Priority 6: No namespace, unqualified → NO prefix (W3C default)
922
+ nil
923
+ end
924
+
925
+ DeclarationPlan::AttributeNode.new(
926
+ local_name: xml_attr.name,
927
+ use_prefix: use_prefix,
928
+ namespace_uri: attr_ns_class&.uri,
929
+ )
930
+ end
931
+
932
+ # Determine element's prefix using the OOP decision system
933
+ #
934
+ # Uses ElementPrefixResolver instead of procedural if-else chain.
935
+ #
936
+ # @param xml_element [XmlDataModel::XmlElement] Element
937
+ # @param mapping [Xml::Mapping] XML mapping
938
+ # @param needs [NamespaceNeeds] Namespace needs
939
+ # @param options [Hash] Serialization options
940
+ # @param is_root [Boolean] Whether this is the root element
941
+ # @param parent_format [Symbol, nil] Parent's format (:prefix or :default)
942
+ # @param parent_namespace_class [Class, nil] Parent's namespace class
943
+ # @param parent_hoisted [Hash] Namespaces hoisted on parent {prefix => uri}
944
+ # @return [String, nil] The prefix to use, or nil for default format
945
+ def find_type_namespace_for_element(xml_element, mapping, needs,
946
+ options)
947
+ # Get mapper_class from options
948
+ mapper_class = options[:mapper_class]
949
+ return nil unless mapper_class
950
+
951
+ # Get attributes from mapper_class
952
+ attributes = if mapper_class.is_a?(Class) && mapper_class.include?(Lutaml::Model::Serialize)
953
+ mapper_class.attributes
954
+ else
955
+ {}
956
+ end
957
+ return nil unless attributes.any?
958
+
959
+ # Find matching element rule
960
+ element_name = xml_element.name.to_s
961
+ matching_rule = mapping.elements.find do |rule|
962
+ rule.name.to_s == element_name
963
+ end
964
+ return nil unless matching_rule
965
+
966
+ # Get attribute definition
967
+ attr_def = attributes[matching_rule.to]
968
+ return nil unless attr_def
969
+
970
+ # Look up type namespace from needs.type_namespaces
971
+ needs.type_namespaces[attr_def&.name]
972
+ end
973
+
974
+ def determine_element_prefix(xml_element, mapping, needs, options,
975
+ is_root: false,
976
+ parent_format: nil,
977
+ parent_namespace_class: nil,
978
+ parent_namespace_prefix: nil,
979
+ parent_hoisted: {},
980
+ element_prefix_explicit: false,
981
+ element_used_prefix: nil)
982
+ # CRITICAL: Check for Type namespace FIRST
983
+ # Type namespaces are declared on Type::Value subclasses and used as
984
+ # prefixes on child elements. They take precedence over element namespace.
985
+ type_ns_class = find_type_namespace_for_element(xml_element, mapping,
986
+ needs, options)
987
+ if type_ns_class
988
+ # If parent uses default format AND Type namespace matches parent's namespace,
989
+ # inherit parent's namespace (return nil for prefix)
990
+ if parent_format == :default && parent_namespace_class&.uri == type_ns_class.uri
991
+ return nil
992
+ end
993
+
994
+ # CRITICAL: Check if parent hoisted this type namespace with a custom prefix
995
+ # When user specifies prefix: "custom", the parent hoists the namespace
996
+ # with that custom prefix, and child elements must use the same prefix
997
+ parent_prefix = parent_hoisted.find do |_prefix, uri|
998
+ uri == type_ns_class.uri
999
+ end&.first
1000
+ if parent_prefix
1001
+ return parent_prefix
1002
+ end
1003
+
1004
+ # CRITICAL: Check if user specified an explicit custom prefix option
1005
+ # This handles the case where parent hasn't hoisted yet AND the type namespace
1006
+ # matches the parent's namespace (i.e., they share the same namespace)
1007
+ use_prefix_option = options[:use_prefix]
1008
+ if use_prefix_option && parent_namespace_class && parent_namespace_class.uri == type_ns_class.uri
1009
+ # Parent has the same namespace as the type namespace
1010
+ # Use the prefix option to maintain consistency
1011
+ case use_prefix_option
1012
+ when String
1013
+ return use_prefix_option
1014
+ when true
1015
+ return parent_namespace_class.prefix_default
1016
+ when false
1017
+ return nil
1018
+ end
1019
+ end
1020
+
1021
+ # Default: use the Type namespace's prefix_default
1022
+ return type_ns_class.prefix_default
1023
+ end
1024
+
1025
+ # If no Type namespace, check element's own namespace
1026
+ return nil unless xml_element.namespace_class
1027
+
1028
+ # NEW: If element used explicit prefix during deserialization, use that prefix.
1029
+ # This handles doubly-defined namespaces where <a:item> and <b:item> both
1030
+ # map to same URI but need different prefixes.
1031
+ # Check: (a) from XmlElement (root), (b) from NamespaceUsage (children)
1032
+ used_prefix = element_used_prefix
1033
+ unless used_prefix
1034
+ # Look up from NamespaceUsage in needs (set during collection from model instance).
1035
+ # CRITICAL: Only use NamespaceUsage.used_prefix when the XmlElement is a
1036
+ # Lutaml::Xml::XmlElement wrapper (from original parsed XML, has namespace_prefix_explicit).
1037
+ # Do NOT use it when the XmlElement is a DataModel::XmlElement (from transformation)
1038
+ # because NamespaceUsage.used_prefix may have been set from a parent/r sibling element.
1039
+ # For DataModel::XmlElement, the prefix must come from @__xml_namespace_prefix on the
1040
+ # XmlElement itself (which is set during transformation for doubly-defined case).
1041
+ ns_key = xml_element.namespace_class.to_key
1042
+ ns_usage = needs.namespaces[ns_key]
1043
+ ns_from_wrapper = xml_element.is_a?(Lutaml::Xml::XmlElement) &&
1044
+ xml_element.respond_to?(:namespace_prefix_explicit) &&
1045
+ xml_element.namespace_prefix_explicit
1046
+ if ns_from_wrapper
1047
+ used_prefix = ns_usage&.used_prefix
1048
+ end
1049
+ end
1050
+
1051
+ # For the ROOT element: always use DecisionEngine (model's prefix_default).
1052
+ # The root's format should be determined by the namespace's default, not the input.
1053
+ # This prevents mixed content roots from using input prefixes like "examplecom:".
1054
+ #
1055
+ # For CHILD elements: use input prefix when it differs from model default.
1056
+ # This handles doubly-defined namespaces where input uses "xyzabc:" but
1057
+ # the input uses a different prefix than the model defines (e.g., input has
1058
+ # "xyzabc:" but model has prefix_default "a:").
1059
+ #
1060
+ # When used_prefix == model_default_prefix, fall through to DecisionEngine
1061
+ # to preserve the original format decision (default vs prefix).
1062
+ if used_prefix && !is_root
1063
+ ns_class = xml_element.namespace_class
1064
+ model_default_prefix = ns_class.prefix_default
1065
+
1066
+ # Only use used_prefix when it differs from model default
1067
+ # This preserves arbitrary input prefixes (xyzabc:) while allowing
1068
+ # the DecisionEngine to decide format when input matches model default.
1069
+ if model_default_prefix.nil? || used_prefix != model_default_prefix
1070
+ return used_prefix
1071
+ end
1072
+ end
1073
+
1074
+ # Use the OOP decision resolver
1075
+ @prefix_resolver ||= Decisions::ElementPrefixResolver.new
1076
+ decision = @prefix_resolver.resolve_with_decision(
1077
+ xml_element, mapping, needs, options,
1078
+ is_root: is_root,
1079
+ parent_format: parent_format,
1080
+ parent_namespace_class: parent_namespace_class,
1081
+ parent_namespace_prefix: parent_namespace_prefix,
1082
+ parent_hoisted: parent_hoisted,
1083
+ element_used_prefix: element_used_prefix
1084
+ )
1085
+
1086
+ decision.prefix
1087
+ end
1088
+
1089
+ # Build qualified element name with prefix
1090
+ #
1091
+ # @param xml_element [XmlDataModel::XmlElement] Element
1092
+ # @param prefix [String, nil] Prefix (nil = no prefix)
1093
+ # @return [String] Qualified name: "prefix:name" or "name"
1094
+ def build_qualified_element_name(xml_element, prefix)
1095
+ if prefix
1096
+ "#{prefix}:#{xml_element.name}"
1097
+ else
1098
+ xml_element.name
1099
+ end
1100
+ end
1101
+
1102
+ # Determine which xmlns declarations to hoist at this element
1103
+ #
1104
+ # Checks input_formats to preserve input format during round-trip.
1105
+ #
1106
+ # @param xml_element [XmlDataModel::XmlElement] Element
1107
+ # @param mapping [Xml::Mapping] XML mapping
1108
+ # @param needs [NamespaceNeeds] Namespace needs
1109
+ # @param options [Hash] Serialization options (may contain :input_formats)
1110
+ # @param is_root [Boolean] Whether this is the root element
1111
+ # @param parent_hoisted [Hash] Namespaces hoisted on parent {prefix => uri}
1112
+ # @param element_path [Array<String>] Element path in the tree for namespace_locations lookup
1113
+ # @param parent_namespace_class [Class, nil] Parent's namespace class
1114
+ # @param parent_namespace_prefix [String, nil] Parent's actual namespace prefix
1115
+ # @return [Hash<String|nil, String>] xmlns attributes: {prefix_or_nil => uri}
1116
+ def determine_hoisted_declarations(xml_element, mapping, needs,
1117
+ options, is_root: false, parent_hoisted: {}, element_prefix: nil, element_path: [], parent_namespace_class: nil, parent_namespace_prefix: nil)
1118
+ hoisted = {}
1119
+
1120
+ # Compute element_used_prefix the same way it's done in build_element_node.
1121
+ # This is needed because determine_element_prefix is called again inside this method,
1122
+ # and it needs element_used_prefix to correctly determine the prefix.
1123
+ element_used_prefix = if is_root
1124
+ nil
1125
+ elsif xml_element.is_a?(Lutaml::Xml::XmlElement)
1126
+ xml_element.namespace_prefix
1127
+ else
1128
+ xml_element.xml_namespace_prefix
1129
+ end
1130
+
1131
+ # CRITICAL: Get the current element's namespace_scope_configs.
1132
+ # For child elements, use their own namespace_scope, not the parent's.
1133
+ current_scope_configs = get_element_namespace_scope_configs(
1134
+ xml_element, mapping, needs, options
1135
+ )
1136
+
1137
+ # Check if element's namespace is hoisted to root via namespace_scope
1138
+ element_ns_hoisted_to_root = false
1139
+ if xml_element.namespace_class
1140
+ scope_config = find_scope_config_for(xml_element.namespace_class,
1141
+ current_scope_configs)
1142
+ if scope_config
1143
+ ns_usage = needs.namespaces[xml_element.namespace_class.to_key]
1144
+ element_ns_hoisted_to_root = scope_config.always_mode? ||
1145
+ (scope_config.auto_mode? && ns_usage&.used_in&.any?)
1146
+ end
1147
+ end
1148
+
1149
+ # Check if element's namespace was already hoisted on parent (locally)
1150
+ if xml_element.namespace_class
1151
+ ns_uri = xml_element.namespace_class.uri
1152
+ parent_hoisted.value?(ns_uri)
1153
+ end
1154
+
1155
+ # FIRST: Add element's OWN namespace if it has one
1156
+ # This ensures the namespace is declared with the correct format (prefix or default)
1157
+ # even when it's already hoisted by parent, to maintain consistency.
1158
+ if xml_element.namespace_class
1159
+ ns_class = xml_element.namespace_class
1160
+ ns_uri = ns_class.uri
1161
+
1162
+ # Check if namespace_locations has an original URI that should be used instead.
1163
+ # namespace_locations is keyed by element path (e.g., "child/grandchild")
1164
+ # matching the key format from collect_element_namespaces in model_transform.rb.
1165
+ # Use element_path for lookup, not xml_element.name (which is just the local name).
1166
+ #
1167
+ # For round-trip fidelity, ALWAYS use the alias URI from stored plan when available.
1168
+ # The use_prefix option only affects element format (prefix vs default), not the URI.
1169
+ # Users expect round-trip to preserve the exact namespace URI from input.
1170
+ stored_plan = options[:stored_xml_declaration_plan]
1171
+ if stored_plan
1172
+ # For child elements, look up by element path
1173
+ # For root elements (empty path), use namespaces_at_path([]) to get root declarations
1174
+ loc_key = element_path.join("/")
1175
+ element_ns_loc = if is_root
1176
+ stored_plan.namespaces_at_path([])
1177
+ else
1178
+ stored_plan.namespace_locations&.dig(loc_key)
1179
+ end
1180
+ # Check if any URI in the stored location is an alias of the canonical URI
1181
+ element_ns_loc&.each_value do |stored_uri|
1182
+ if ns_class.is_alias?(stored_uri)
1183
+ # Use the original alias URI instead of canonical
1184
+ ns_uri = stored_uri
1185
+ break
1186
+ end
1187
+ end
1188
+ end
1189
+ # Check if namespace is hoisted on parent
1190
+ # When namespace has uri_aliases, the parent may have declared a different
1191
+ # URI (alias or canonical) than what this element wants to use.
1192
+ # Rules:
1193
+ # 1. Exact match → already hoisted, don't re-declare
1194
+ # 2. Parent declared alias, child wants canonical → already hoisted (alias covers canonical)
1195
+ # 3. Parent declared canonical/alias-A, child wants alias-B → NOT hoisted (child must declare its alias)
1196
+ # This ensures round-trip fidelity: if input used alias URI, output preserves it.
1197
+ ns_hoisted_by_parent = parent_hoisted.value?(ns_uri)
1198
+ if !ns_hoisted_by_parent && ns_class.respond_to?(:all_uris) &&
1199
+ ns_uri == ns_class.uri # child is using canonical URI
1200
+ # Parent declared an alias of this namespace — child doesn't need to re-declare
1201
+ # because the alias already establishes the namespace binding
1202
+ ns_hoisted_by_parent = ns_class.uri_aliases.any? do |alias_uri|
1203
+ parent_hoisted.value?(alias_uri)
1204
+ end
1205
+ end
1206
+
1207
+ # Check if namespace is hoisted to root via namespace_scope (for non-root elements)
1208
+ element_ns_hoisted_to_root && !is_root
1209
+
1210
+ # Determine the prefix to use for this namespace
1211
+ if !ns_hoisted_by_parent
1212
+ # Namespace is NOT already hoisted by parent - need to determine prefix
1213
+ element_prefix = determine_element_prefix(xml_element, mapping,
1214
+ needs, options, is_root: is_root, parent_hoisted: parent_hoisted, element_used_prefix: element_used_prefix, parent_namespace_class: parent_namespace_class, parent_namespace_prefix: parent_namespace_prefix)
1215
+
1216
+ # W3C elementFormDefault="unqualified": prefer prefix format so children
1217
+ # can be in blank namespace (no xmlns attribute). Only for non-root elements
1218
+ # since elementFormDefault only applies to local elements.
1219
+ # CRITICAL: Only applies when explicitly set, not when defaulted to :unqualified.
1220
+ if element_prefix.nil? && ns_class.element_form_default_set? &&
1221
+ ns_class.element_form_default == :unqualified && !is_root
1222
+ element_prefix = ns_class.prefix_default || "ns"
1223
+ end
1224
+
1225
+ hoisted[element_prefix] = ns_uri
1226
+ elsif element_prefix
1227
+ # Namespace is already hoisted by parent, and we have an explicit prefix
1228
+ # Check if parent has the SAME prefix declaration (accounting for URI aliases)
1229
+ parent_uri_for_prefix = parent_hoisted[element_prefix]
1230
+ all_uris = ns_class.respond_to?(:all_uris) ? ns_class.all_uris : [ns_uri]
1231
+ parent_has_same_prefix = parent_uri_for_prefix && all_uris.include?(parent_uri_for_prefix)
1232
+ if parent_has_same_prefix
1233
+ # Parent already declared this namespace with the same prefix - don't re-declare
1234
+ # Just keep track that we're using the parent's prefix (no need to add to hoisted)
1235
+ else
1236
+ # Parent has different prefix or no prefix - add our declaration
1237
+ hoisted[element_prefix] = ns_uri
1238
+ end
1239
+ else
1240
+ # Namespace is hoisted by parent, and we don't have an explicit prefix
1241
+ # W3C XML Namespaces 1.0 §6.2: Child elements inherit namespace from parent
1242
+ # DO NOT re-declare the namespace - the child will inherit it
1243
+ # This prevents redundant xmlns declarations on nested elements with same namespace
1244
+ end
1245
+
1246
+ # CRITICAL FIX: If root element uses default format (nil prefix) and child elements
1247
+ # need prefix format for the same namespace (due to form: :qualified), also declare
1248
+ # the namespace with prefix format on the root element.
1249
+ # This allows child elements to use the prefix without declaring it locally.
1250
+ # IMPORTANT: This only applies to the element's OWN namespace, not type namespaces.
1251
+ # Type namespaces should be declared locally on the element that uses the type.
1252
+ # Check if any child elements have form: :qualified for this namespace
1253
+ # by checking the children's form attribute in the XmlElement tree
1254
+ #
1255
+ # ADDITIONAL CHECK: Skip if namespace was NOT declared at root in input XML.
1256
+ # Use namespaces_at_path([]) to verify this namespace was actually at root level.
1257
+ # Note: namespace_locations only has child paths, not root. Root namespaces
1258
+ # are stored in root_node.hoisted_declarations, which namespaces_at_path returns.
1259
+ if is_root && hoisted.key?(nil) && hoisted[nil] == ns_uri && xml_element.respond_to?(:children)
1260
+ stored_plan = options[:stored_xml_declaration_plan]
1261
+ root_ns_at_input = stored_plan&.namespaces_at_path([])
1262
+ namespace_was_at_root = if root_ns_at_input
1263
+ root_ns_at_input.value?(ns_uri)
1264
+ else
1265
+ true # No location data, assume it was at root
1266
+ end
1267
+
1268
+ if namespace_was_at_root
1269
+ child_needs_prefix = xml_element.children.any? do |child|
1270
+ next unless child.is_a?(Lutaml::Xml::DataModel::XmlElement)
1271
+
1272
+ # Check if child has form: :qualified and same namespace
1273
+ child.form == :qualified && child.namespace_class&.uri == ns_uri
1274
+ end
1275
+ if child_needs_prefix
1276
+ prefix = ns_class.prefix_default
1277
+ hoisted[prefix] = ns_uri
1278
+ end
1279
+ end
1280
+ end
1281
+ end
1282
+
1283
+ # SECOND: Add namespace_scope namespaces (ONLY at root!)
1284
+ if is_root
1285
+ stored_plan = options[:stored_xml_declaration_plan]
1286
+ current_scope_configs.each do |scope_config|
1287
+ ns_class = scope_config.namespace_class
1288
+ ns_uri = ns_class.uri
1289
+
1290
+ # Skip if already added (element's own namespace)
1291
+ next if ns_class == xml_element.namespace_class
1292
+
1293
+ # CRITICAL: Skip if namespace URI is already in hoisted hash
1294
+ # An element can declare the same URI with both default and prefix formats
1295
+ next if hoisted.value?(ns_uri) || hoisted.key?(ns_class.prefix_default)
1296
+
1297
+ # NEW: Skip if namespace was NOT declared at root in input XML.
1298
+ # Use namespace_locations to verify this namespace was actually at root level.
1299
+ # If namespace_locations shows it was only at child paths, do NOT hoist to root.
1300
+ root_ns_at_input = stored_plan&.namespaces_at_path([])
1301
+ if root_ns_at_input && !root_ns_at_input.value?(ns_uri)
1302
+ # Namespace was not declared at root in input - skip hoisting
1303
+ next
1304
+ end
1305
+
1306
+ # Check :always mode or :auto mode with usage
1307
+ ns_usage = needs.namespace(ns_class.to_key)
1308
+ should_declare_here = scope_config.always_mode? ||
1309
+ (scope_config.auto_mode? && ns_usage&.used_in&.any?)
1310
+
1311
+ if should_declare_here
1312
+ prefix = ns_class.prefix_default
1313
+ hoisted[prefix] = ns_uri
1314
+ end
1315
+ end
1316
+ end
1317
+
1318
+ # THIRD: Add type namespaces
1319
+ # Type namespaces are declared on PARENT elements and used by child elements.
1320
+ # W3C rule: Namespaces in attributes MUST use prefix format.
1321
+ # Type namespaces for elements MUST also be declared at root with prefix.
1322
+ # Example: ContactInfo declares xmlns:name for personName's name:prefix attribute.
1323
+ # Example: Document declares xmlns:dc for title's dc:title element.
1324
+ #
1325
+ # CRITICAL: Type namespaces respect namespace_scope directive.
1326
+ # When namespace_scope is configured, hoist type namespaces to root.
1327
+ # When namespace_scope is NOT configured, type namespaces are declared
1328
+ # locally on the elements that use them.
1329
+ if is_root
1330
+ # Check if namespace_scope is configured
1331
+ has_namespace_scope = !current_scope_configs.empty?
1332
+
1333
+ # Only hoist type namespaces to root when namespace_scope is configured
1334
+ if has_namespace_scope
1335
+ # Type attribute namespaces
1336
+ needs.type_attribute_namespaces.each do |ns_class|
1337
+ ns_uri = ns_class.uri
1338
+ next if hoisted.value?(ns_uri) # Skip if already declared
1339
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1340
+
1341
+ # If namespace_scope is configured, only hoist if in scope
1342
+ scope_config = find_scope_config_for(ns_class,
1343
+ current_scope_configs)
1344
+ next unless scope_config
1345
+
1346
+ # Type attribute namespaces MUST use prefix format (W3C rule)
1347
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1348
+ hoisted[prefix] = ns_uri
1349
+ end
1350
+
1351
+ # Type element namespaces
1352
+ needs.type_element_namespaces.each do |ns_class|
1353
+ ns_uri = ns_class.uri
1354
+ next if hoisted.value?(ns_uri) # Skip if already declared
1355
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1356
+
1357
+ # CRITICAL: Type namespaces are different from child element namespaces.
1358
+ # Type namespaces are declared on Type::Value subclasses (via xml_namespace
1359
+ # directive) and MUST ALWAYS be hoisted to root with prefix format (W3C
1360
+ # constraint: only one default namespace per element).
1361
+ #
1362
+ # The restriction below applies ONLY to child element namespaces (from nested
1363
+ # models), NOT to Type namespaces. Type namespaces are about TYPE identity,
1364
+ # not about element structure.
1365
+ #
1366
+ # Examples of child element namespaces (should NOT be hoisted if different):
1367
+ # - Root has XMI namespace, child model has XMI_NEW namespace → child declares
1368
+ # - Root has NO namespace, child model has XMI namespace → child declares
1369
+ #
1370
+ # Examples of Type namespaces (should ALWAYS be hoisted):
1371
+ # - Root has any namespace, attribute type has XMI namespace → hoist XMI
1372
+ # - Root has NO namespace, attribute type has XMI namespace → hoist XMI
1373
+
1374
+ # If namespace_scope is configured, only hoist if in scope
1375
+ scope_config = find_scope_config_for(ns_class,
1376
+ current_scope_configs)
1377
+ next unless scope_config
1378
+
1379
+ # Type element namespaces MUST use prefix format
1380
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1381
+ hoisted[prefix] = ns_uri
1382
+ end
1383
+ else
1384
+ # Root element without namespace_scope: hoist type namespaces
1385
+ # Type namespaces MUST use prefix format (W3C rule)
1386
+ #
1387
+ # CRITICAL: Don't hoist type namespaces that are also child element
1388
+ # namespaces. When a type namespace is also a child's element namespace, it
1389
+ # should be declared on that child element (not hoisted to root).
1390
+
1391
+ # Type element namespaces (for Type::Value classes used by root's attributes)
1392
+ needs.type_element_namespaces.each do |ns_class|
1393
+ ns_uri = ns_class.uri
1394
+ next if hoisted.value?(ns_uri) # Skip if already declared
1395
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1396
+
1397
+ # Check if this namespace is used by any child element as its element namespace
1398
+ # If so, don't hoist - let the child declare it locally
1399
+ # UNLESS the parent also uses this namespace for its attributes
1400
+ child_uses_namespace = needs.children&.any? do |_attr_name, child_needs|
1401
+ child_needs.namespaces.any? do |_key, ns_usage|
1402
+ ns_usage.used_in_elements? && ns_usage.namespace_class.uri == ns_uri
1403
+ end
1404
+ end
1405
+
1406
+ # Only skip hoisting if child uses namespace AND parent doesn't use it for attributes
1407
+ # Check if parent element instance has attributes with this namespace
1408
+ parent_has_attr_with_ns = if xml_element.respond_to?(:attributes)
1409
+ xml_element.attributes.any? do |xml_attr|
1410
+ next false unless xml_attr.namespace_class
1411
+
1412
+ xml_attr.namespace_class.uri == ns_uri
1413
+ end
1414
+ else
1415
+ # For nil/Class root_element, check if mapping has attributes with this namespace
1416
+ # This handles the case where parent doesn't have the attribute set
1417
+ # Only hoist if parent's MAPPING declares attributes with this namespace
1418
+ mapping.attributes.any? do |attr_rule|
1419
+ next false unless attr_rule.attribute?
1420
+
1421
+ # Get the mapper_class to find attribute definition
1422
+ mapper_class = options[:mapper_class] || mapping.owner
1423
+ next false unless mapper_class
1424
+ next false unless mapper_class.is_a?(Class) &&
1425
+ mapper_class.include?(Lutaml::Model::Serialize)
1426
+
1427
+ attr_def = mapper_class.attributes[attr_rule.to]
1428
+ next false unless attr_def
1429
+
1430
+ # Check if this attribute's type has the namespace
1431
+ type_ns_class = attr_def.type_namespace_class(register_for(mapper_class))
1432
+ type_ns_class&.uri == ns_uri
1433
+ end
1434
+ end
1435
+ next if child_uses_namespace && !parent_has_attr_with_ns
1436
+
1437
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1438
+ hoisted[prefix] = ns_uri
1439
+ end
1440
+
1441
+ # Type attribute namespaces (for Type::Value classes used in child element attributes)
1442
+ # CRITICAL: Don't hoist if namespace is also child element's namespace
1443
+ needs.type_attribute_namespaces.each do |ns_class|
1444
+ ns_uri = ns_class.uri
1445
+ next if hoisted.value?(ns_uri) # Skip if already declared
1446
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1447
+
1448
+ # Check if this namespace is used by any child element as its element namespace
1449
+ # If so, don't hoist - let the child declare it locally
1450
+ child_uses_namespace = needs.children&.any? do |_attr_name, child_needs|
1451
+ child_needs.namespaces.any? do |_key, ns_usage|
1452
+ ns_usage.used_in_elements? && ns_usage.namespace_class.uri == ns_uri
1453
+ end
1454
+ end
1455
+
1456
+ # Only skip hoisting if child uses namespace AND parent doesn't use it for attributes
1457
+ parent_has_attr_with_ns = if xml_element.respond_to?(:attributes)
1458
+ xml_element.attributes.any? do |xml_attr|
1459
+ next false unless xml_attr.namespace_class
1460
+
1461
+ xml_attr.namespace_class.uri == ns_uri
1462
+ end
1463
+ else
1464
+ # For nil/Class root_element, check if mapping has attributes with this namespace
1465
+ mapping.attributes.any? do |attr_rule|
1466
+ next false unless attr_rule.attribute?
1467
+
1468
+ mapper_class = options[:mapper_class] || mapping.owner
1469
+ next false unless mapper_class
1470
+ next false unless mapper_class.is_a?(Class) &&
1471
+ mapper_class.include?(Lutaml::Model::Serialize)
1472
+
1473
+ attr_def = mapper_class.attributes[attr_rule.to]
1474
+ next false unless attr_def
1475
+
1476
+ type_ns_class = attr_def.type_namespace_class(register_for(mapper_class))
1477
+ type_ns_class&.uri == ns_uri
1478
+ end
1479
+ end
1480
+
1481
+ next if child_uses_namespace && !parent_has_attr_with_ns
1482
+
1483
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1484
+ hoisted[prefix] = ns_uri
1485
+ end
1486
+ end
1487
+ else
1488
+ # For non-root (child) elements, add their own type namespaces
1489
+ # CRITICAL: Child elements with type namespace attributes need those
1490
+ # namespaces declared on themselves (W3C compliance)
1491
+ #
1492
+ # Get the child's own namespace needs by matching the current element
1493
+ # to its corresponding attribute name in the parent's mapping
1494
+ child_attr_name = find_child_attribute_name(xml_element, mapping,
1495
+ options)
1496
+ if child_attr_name
1497
+ child_needs = needs.child(child_attr_name)
1498
+ if child_needs
1499
+ # Add child's type element namespaces (for Type::Value attributes)
1500
+ # These need to be hoisted to the child element
1501
+ child_needs.type_element_namespaces.each do |ns_class|
1502
+ ns_uri = ns_class.uri
1503
+ next if hoisted.value?(ns_uri) # Skip if already declared
1504
+ next if parent_hoisted.value?(ns_uri) # Skip if parent already declared
1505
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1506
+
1507
+ # Type namespaces MUST use prefix format (W3C rule)
1508
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1509
+ hoisted[prefix] = ns_uri
1510
+ end
1511
+
1512
+ # Add child's type attribute namespaces
1513
+ # CRITICAL: Skip if namespace is child's own element namespace
1514
+ # The element's namespace declaration already covers it
1515
+ child_needs.type_attribute_namespaces.each do |ns_class|
1516
+ ns_uri = ns_class.uri
1517
+ next if hoisted.value?(ns_uri) # Skip if already declared
1518
+ next if parent_hoisted.value?(ns_uri) # Skip if parent already declared
1519
+ next if ns_class == xml_element.namespace_class # Skip element's own namespace
1520
+
1521
+ # Type attribute namespaces MUST use prefix format (W3C rule)
1522
+ prefix = ns_class.prefix_default || "ns#{hoisted.keys.length}"
1523
+ hoisted[prefix] = ns_uri
1524
+ end
1525
+ end
1526
+ end
1527
+ end
1528
+
1529
+ # FOURTH: Add namespaces NOT in namespace_scope (LOCAL hoisting)
1530
+ # W3C minimal-subtree principle: declare namespace at first element using it
1531
+ if !is_root
1532
+ needs.namespaces.each_value do |ns_usage|
1533
+ ns_class = ns_usage.namespace_class
1534
+
1535
+ # Skip if already added (element's own namespace)
1536
+ next if ns_class == xml_element.namespace_class
1537
+
1538
+ # Skip if already hoisted on parent (don't redeclare!)
1539
+ next if parent_hoisted.value?(ns_class.uri)
1540
+
1541
+ # CRITICAL: Skip if this namespace is ONLY used by child elements (not by
1542
+ # the current element). Child elements should declare their own namespace
1543
+ # locally using default format. But if the current element uses this namespace
1544
+ # for its attributes, it should be hoisted.
1545
+ # Check: if NOT used in attributes AND used in elements → skip hoisting
1546
+ # NOTE: Also check type_attribute_namespaces (attribute type namespaces)
1547
+ used_in_attributes = ns_usage.used_in_attributes? || needs.type_attribute_namespaces.include?(ns_class)
1548
+ next if !used_in_attributes && ns_usage.used_in_elements?
1549
+
1550
+ scope_config = find_scope_config_for(ns_class,
1551
+ current_scope_configs)
1552
+
1553
+ # Only hoist if NOT in namespace_scope (local hoisting)
1554
+ # Check if any child/grandchild uses this namespace
1555
+ if !scope_config && element_needs_namespace?(xml_element,
1556
+ ns_class)
1557
+ prefix = ns_class.prefix_default
1558
+ hoisted[prefix] = ns_class.uri
1559
+ end
1560
+ end
1561
+ end
1562
+
1563
+ # PRESERVATION: For root element, add stored input namespace declarations
1564
+ # that were declared AT ROOT in the original XML.
1565
+ # This includes namespaces like xmlns:xi that were in input at root level
1566
+ # but are not "needed" by model. These namespaces may be required for
1567
+ # downstream processing (XInclude, XSchema, etc.)
1568
+ #
1569
+ # For doubly-defined namespaces (same URI with different prefixes), we allow
1570
+ # each prefix variant to be preserved if used by children.
1571
+ #
1572
+ # CRITICAL: Only preserve namespaces that were ORIGINALLY declared at root.
1573
+ # Namespaces declared on child elements in the input should remain on children.
1574
+ # NOTE: PRESERVATION should always run when we have a stored plan, because
1575
+ # unused namespaces (like xmlns:xsi for schemaLocation) should be preserved
1576
+ # for round-trip fidelity regardless of prefix formatting options.
1577
+ stored_plan = options[:stored_xml_declaration_plan]
1578
+ if is_root && stored_plan
1579
+
1580
+ # Get root-level namespaces from location tracking.
1581
+ # This properly distinguishes namespaces declared at root vs hoisted there.
1582
+ root_level_namespaces = stored_plan&.namespaces_at_path([])
1583
+
1584
+ # Track namespaces that are in child paths (not root) in namespace_locations
1585
+ # These should NOT be on root in the input XML
1586
+ child_only_namespaces = {}
1587
+ stored_plan&.namespace_locations&.each do |path, ns_hash|
1588
+ next if path.empty? # Skip root path
1589
+
1590
+ ns_hash.each do |prefix, uri|
1591
+ child_only_namespaces[[prefix, uri]] = true
1592
+ end
1593
+ end
1594
+
1595
+ # Get namespace_locations to verify which namespaces were actually declared at root
1596
+ # in the input XML. This prevents hoisting namespaces that were declared on child
1597
+ # elements but got incorrectly added to root's hoisted during FIRST phase.
1598
+ input_root_ns = {}
1599
+ if stored_plan&.namespace_locations
1600
+ # Aggregate all namespaces from child paths
1601
+ child_ns = {}
1602
+ stored_plan.namespace_locations.each_value do |ns_hash|
1603
+ ns_hash.each do |prefix, uri|
1604
+ child_ns[[prefix, uri]] = true
1605
+ end
1606
+ end
1607
+ # Namespaces in root's hoisted but NOT in any child path were actually at root
1608
+ root_level_namespaces&.each do |prefix, uri|
1609
+ if prefix != :not_root && !child_ns.key?([
1610
+ prefix, uri
1611
+ ])
1612
+ input_root_ns[prefix] =
1613
+ uri
1614
+ end
1615
+ end
1616
+ end
1617
+
1618
+ if input_root_ns.any?
1619
+ root_level_namespaces = input_root_ns
1620
+ end
1621
+
1622
+ if root_level_namespaces
1623
+ root_level_namespaces.each do |prefix, uri|
1624
+ # Skip if same prefix already used for different URI
1625
+ next if hoisted.key?(prefix) && hoisted[prefix] != uri
1626
+
1627
+ # Skip if this namespace is a child element's OWN element namespace
1628
+ # (not a type namespace). Children should declare their own namespace
1629
+ # locally rather than having it hoisted to root.
1630
+ child_own_element_ns = needs.children&.any? do |_attr_name, child_needs|
1631
+ child_needs.namespaces.values.any? do |ns_usage|
1632
+ ns_usage.namespace_class.uri == uri &&
1633
+ ns_usage.used_in_elements? &&
1634
+ needs.type_namespace_classes.none? { |tc| tc.uri == uri }
1635
+ end
1636
+ end
1637
+ next if child_own_element_ns
1638
+
1639
+ # Check if children use this specific prefix variant
1640
+ # This enables doubly-defined namespace preservation
1641
+ child_uses_this_prefix = needs.children&.any? do |_attr_name, child_needs|
1642
+ child_needs.namespaces.values.any? do |ns_usage|
1643
+ ns_usage.used_prefix == prefix &&
1644
+ ns_usage.namespace_class.uri == uri
1645
+ end
1646
+ end
1647
+
1648
+ # Hoist if:
1649
+ # - URI not yet declared (no prefix+URI combo), OR
1650
+ # - This specific prefix variant is used by children (doubly-defined ns)
1651
+ uri_already_hoisted = hoisted.value?(uri)
1652
+ if !uri_already_hoisted || child_uses_this_prefix
1653
+ hoisted[prefix] = uri
1654
+ end
1655
+ end
1656
+ elsif stored_plan&.root_node&.hoisted_declarations
1657
+ # Fallback: Legacy behavior for plans without location data
1658
+ # Only add namespaces that are NOT needed by any child
1659
+ #
1660
+ # CRITICAL: If namespace_locations has child entries but root path is empty,
1661
+ # it means the root's own namespaces were NOT captured during parsing.
1662
+ # In this case, we should NOT add anything from fallback to avoid
1663
+ # incorrectly adding child namespaces to root.
1664
+ root_path_in_locations = stored_plan.namespace_locations&.key?("")
1665
+ if root_path_in_locations && stored_plan.namespace_locations[""].to_h.empty?
1666
+ # Root path exists but is empty - skip fallback to avoid adding child namespaces to root
1667
+ else
1668
+ stored_hoisted = stored_plan.root_node.hoisted_declarations
1669
+ stored_hoisted.each do |prefix, uri|
1670
+ # Skip if this namespace is in child_only_namespaces
1671
+ # (declared on a child element in the input)
1672
+ next if child_only_namespaces.key?([prefix, uri])
1673
+
1674
+ # Skip if same prefix already used for different URI
1675
+ next if hoisted.key?(prefix) && hoisted[prefix] != uri
1676
+
1677
+ # Check if any child element needs this namespace
1678
+ child_needs_ns = needs.children&.any? do |_attr_name, child_needs|
1679
+ child_needs.namespaces.any? do |_key, ns_usage|
1680
+ ns_usage.namespace_class&.uri == uri
1681
+ end
1682
+ end
1683
+ next if child_needs_ns
1684
+
1685
+ # Safe to preserve at root
1686
+ hoisted[prefix] = uri
1687
+ end
1688
+ end
1689
+ end
1690
+ end
1691
+
1692
+ # FIFTH: Add XSI namespace if any Namespace in scope has schema_location
1693
+ # Schema location is handled by DeclarationPlan.build_schema_location_attr
1694
+ # which builds xsi:schemaLocation from all Namespace.schema_location values
1695
+ if namespaces_have_schema_location?(needs, options)
1696
+ xsi_uri = W3c::XsiNamespace.uri
1697
+ xsi_prefix = W3c::XsiNamespace.prefix_default || "xsi"
1698
+ hoisted[xsi_prefix] = xsi_uri unless hoisted.value?(xsi_uri)
1699
+ end
1700
+
1701
+ hoisted
1702
+ end
1703
+
1704
+ # Check if any Namespace in scope has schema_location
1705
+ #
1706
+ # @param needs [NamespaceNeeds] Namespace needs
1707
+ # @param options [Hash] Serialization options
1708
+ # @return [Boolean] True if any namespace has schema_location
1709
+ def namespaces_have_schema_location?(needs, _options)
1710
+ return false unless needs
1711
+
1712
+ # Check all namespace classes in needs
1713
+ needs.all_namespace_classes.any? do |ns_class|
1714
+ ns_class.respond_to?(:schema_location) && ns_class.schema_location
1715
+ end
1716
+ end
1717
+
1718
+ # Find the attribute name for a child XmlElement
1719
+ #
1720
+ # When building child element nodes, we need to match the XmlElement to its
1721
+ # corresponding attribute name in the parent's mapping to access the child's
1722
+ # own namespace needs.
1723
+ #
1724
+ # @param xml_element [XmlDataModel::XmlElement] The child element
1725
+ # @param mapping [Xml::Mapping] The current element's mapping (parent's for child elements)
1726
+ # @param options [Hash] Serialization options (may contain :parent_mapping)
1727
+ # @return [Symbol, nil] The attribute name, or nil if not found
1728
+ def find_child_attribute_name(xml_element, mapping, options = {})
1729
+ # Use parent's mapping if available (for child elements)
1730
+ search_mapping = options[:parent_mapping] || mapping
1731
+
1732
+ element_name = xml_element.name.to_s
1733
+ matching_rule = search_mapping.elements.find do |rule|
1734
+ rule.name.to_s == element_name
1735
+ end
1736
+
1737
+ matching_rule&.to
1738
+ end
1739
+
1740
+ # Get the current element's namespace_scope_configs
1741
+ #
1742
+ # For child elements, use their own namespace_scope, not the parent's.
1743
+ # This ensures that namespace_scope directives are scoped to the model that defines them.
1744
+ #
1745
+ # @param xml_element [XmlDataModel::XmlElement] The element
1746
+ # @param mapping [Xml::Mapping] The element's mapping
1747
+ # @param needs [NamespaceNeeds] Namespace needs
1748
+ # @param options [Hash] Serialization options
1749
+ # @return [Array<NamespaceScopeConfig>] The element's namespace_scope_configs
1750
+ def get_element_namespace_scope_configs(_xml_element, _mapping, needs,
1751
+ _options)
1752
+ # Use the parent's namespace_scope_configs
1753
+ needs.namespace_scope_configs
1754
+ end
1755
+
1756
+ # Find a scope config for a namespace class
1757
+ #
1758
+ # @param ns_class [Class] The namespace class
1759
+ # @param scope_configs [Array<NamespaceScopeConfig>] The scope configs to search
1760
+ # @return [NamespaceScopeConfig, nil] The matching scope config, or nil
1761
+ def find_scope_config_for(ns_class, scope_configs)
1762
+ scope_configs.find { |config| config.namespace_class == ns_class }
1763
+ end
1764
+
1765
+ # Build global prefix registry from needs
1766
+ #
1767
+ # @param needs [NamespaceNeeds] Namespace needs
1768
+ # @return [Hash<String, String>] URI => prefix mapping
1769
+ def build_prefix_registry(needs)
1770
+ registry = {}
1771
+ needs.namespaces.each_value do |ns_usage|
1772
+ ns_class = ns_usage.namespace_class
1773
+ if ns_class.prefix_default
1774
+ registry[ns_class.uri] =
1775
+ ns_class.prefix_default
1776
+ end
1777
+ end
1778
+ registry
1779
+ end
1780
+
1781
+ # Check if element or its descendants use a namespace
1782
+ #
1783
+ # @param xml_element [XmlDataModel::XmlElement] Element to check
1784
+ # @param ns_class [Class] Namespace class to search for
1785
+ # @return [Boolean] true if namespace is used in subtree
1786
+ def element_needs_namespace?(xml_element, ns_class)
1787
+ # Check direct children
1788
+ xml_element.children.each do |child|
1789
+ next unless child.is_a?(Lutaml::Xml::DataModel::XmlElement)
1790
+
1791
+ # Does child use this namespace?
1792
+ return true if child.namespace_class == ns_class
1793
+
1794
+ # Does child have attributes using this namespace?
1795
+ child.attributes.each do |attr|
1796
+ return true if attr.namespace_class == ns_class
1797
+ end
1798
+
1799
+ # Recurse to grandchildren
1800
+ return true if element_needs_namespace?(child, ns_class)
1801
+ end
1802
+
1803
+ false
1804
+ end
1805
+
1806
+ # Check if element is a native type element (leaf with text content)
1807
+ #
1808
+ # Native type elements (like :string, :integer) are simple values
1809
+ # that need xmlns="" when parent uses default namespace format.
1810
+ # Child models are complex elements with their own structure.
1811
+ #
1812
+ # @param xml_element [XmlDataModel::XmlElement] Element to check
1813
+ # @return [Boolean] true if element is a native type element
1814
+ def native_type_element?(xml_element)
1815
+ # Native type elements have:
1816
+ # - text_content (not nil)
1817
+ # - No element children (all children are Strings, not XmlElement)
1818
+ return false unless xml_element.text_content
1819
+
1820
+ xml_element.children.all?(String)
1821
+ end
1822
+
1823
+ # Build schema_location attribute value from all Namespace.schema_location values
1824
+ #
1825
+ # @param needs [NamespaceNeeds] Namespace needs
1826
+ # @return [Hash, nil] { "xsi:schemaLocation" => "uri1 loc1 uri2 loc2" } or nil
1827
+ def build_schema_location_attr_for_needs(needs)
1828
+ return nil unless needs
1829
+
1830
+ # Collect all namespace classes that have schema_location
1831
+ namespaces_with_schema = needs.all_namespace_classes.select do |ns_class|
1832
+ ns_class.respond_to?(:schema_location) && ns_class.schema_location
1833
+ end
1834
+
1835
+ return nil if namespaces_with_schema.empty?
1836
+
1837
+ # Build xsi:schemaLocation value
1838
+ value = namespaces_with_schema.map do |ns_class|
1839
+ "#{ns_class.uri} #{ns_class.schema_location}"
1840
+ end.join(" ")
1841
+
1842
+ # Get XSI prefix from hoisted declarations or use default
1843
+ xsi_prefix = W3c::XsiNamespace.prefix_default || "xsi"
1844
+
1845
+ { "#{xsi_prefix}:schemaLocation" => value }
1846
+ end
1847
+ end
1848
+ end
1849
+ end