moxml 0.1.13 → 0.1.15

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +117 -66
  3. data/Gemfile +1 -0
  4. data/README.adoc +11 -9
  5. data/Rakefile +3 -1
  6. data/docs/_pages/configuration.adoc +22 -19
  7. data/docs/_tutorials/namespace-handling.adoc +5 -5
  8. data/lib/moxml/adapter/base.rb +8 -3
  9. data/lib/moxml/adapter/customized_libxml/entity_reference.rb +23 -0
  10. data/lib/moxml/adapter/customized_libxml.rb +18 -0
  11. data/lib/moxml/adapter/customized_oga/xml_generator.rb +2 -2
  12. data/lib/moxml/adapter/customized_oga.rb +10 -0
  13. data/lib/moxml/adapter/customized_ox/entity_reference.rb +25 -0
  14. data/lib/moxml/adapter/customized_ox.rb +12 -0
  15. data/lib/moxml/adapter/customized_rexml/entity_reference.rb +19 -0
  16. data/lib/moxml/adapter/customized_rexml/formatter.rb +2 -0
  17. data/lib/moxml/adapter/customized_rexml.rb +11 -0
  18. data/lib/moxml/adapter/headed_ox.rb +9 -3
  19. data/lib/moxml/adapter/libxml.rb +76 -62
  20. data/lib/moxml/adapter/nokogiri.rb +4 -5
  21. data/lib/moxml/adapter/oga.rb +50 -26
  22. data/lib/moxml/adapter/ox.rb +189 -41
  23. data/lib/moxml/adapter/rexml.rb +27 -8
  24. data/lib/moxml/attribute.rb +3 -0
  25. data/lib/moxml/builder.rb +1 -0
  26. data/lib/moxml/config.rb +7 -7
  27. data/lib/moxml/document.rb +5 -1
  28. data/lib/moxml/document_builder.rb +37 -31
  29. data/lib/moxml/element.rb +13 -5
  30. data/lib/moxml/entity_registry.rb +36 -0
  31. data/lib/moxml/node.rb +23 -2
  32. data/lib/moxml/node_set.rb +43 -15
  33. data/lib/moxml/version.rb +1 -1
  34. data/lib/moxml/xml_utils.rb +1 -1
  35. data/spec/integration/shared_examples/edge_cases.rb +3 -0
  36. data/spec/moxml/adapter/oga_spec.rb +62 -0
  37. data/spec/moxml/adapter/shared_examples/adapter_contract.rb +1 -12
  38. data/spec/moxml/allocation_benchmark_spec.rb +96 -0
  39. data/spec/moxml/allocation_guard_spec.rb +282 -0
  40. data/spec/moxml/builder_spec.rb +22 -0
  41. data/spec/moxml/config_spec.rb +11 -11
  42. data/spec/moxml/doctype_spec.rb +41 -0
  43. data/spec/moxml/lazy_parse_spec.rb +115 -0
  44. data/spec/moxml/namespace_uri_validation_spec.rb +11 -3
  45. data/spec/moxml/node_cache_spec.rb +110 -0
  46. data/spec/moxml/node_set_cache_spec.rb +90 -0
  47. data/spec/moxml/xml_utils_spec.rb +32 -0
  48. data/spec/support/allocation_helper.rb +165 -0
  49. data/spec/support/w3c_namespace_helpers.rb +2 -1
  50. metadata +15 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a3d9ee4016fae355b5533b22d992f4a127e788b1a39cef001458c3085133f42d
4
- data.tar.gz: 79c85ee71c8def65d684cf1243d44871a9120260ec505d48341ef0b96eaa31e0
3
+ metadata.gz: 41df5c029544cf0136de3a87a60a1926df913b973b2653f7bb56c2e3725176b8
4
+ data.tar.gz: 59ef11350181ac4b5ddec209128f26cc17e629cb778776b6a198df6853a5ce22
5
5
  SHA512:
6
- metadata.gz: fda8c13b2491e63200ed771dd85cd29fa15a7bc297583fe8c33b8d9ad8b93b05b4dca29d253d798397c37d3b72304d0588d5f11c95de6e16aba74ea26472cdbb
7
- data.tar.gz: d1853370b28eee67a4df08cd4b4bdbc83816866282f731eeca15870da119ff1e643898db823d49ee5e98ae1bcfc34370672b29e38abc5ccab542088bb239e3d9
6
+ metadata.gz: c1e5e7f0a5a036bc900bd2d13522ff381cdb01fdc02d501aac6b328816bf4c2a953a0f47721665b1a209b9cdf89f29081a6410b286d6f4bdab7389b411e5475e
7
+ data.tar.gz: 7d05e346a9b0e32da8de5e26b29500dee443fed6c356ba12a3dafc4247b9fb2be454a02d41105e370d91c363f6bfd8445fa79c664003fa1e8f7eca8adb8da31e
data/.rubocop_todo.yml CHANGED
@@ -1,96 +1,97 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2026-04-05 03:01:25 UTC using RuboCop version 1.86.0.
3
+ # on 2026-04-22 01:41:34 UTC using RuboCop version 1.86.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
- # Offense count: 5
9
+ # Offense count: 18
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: EnforcedStyle, IndentationWidth.
12
12
  # SupportedStyles: with_first_argument, with_fixed_indentation
13
13
  Layout/ArgumentAlignment:
14
14
  Exclude:
15
- - 'lib/moxml/config.rb'
16
- - 'lib/moxml/entity_registry.rb'
17
- - 'spec/moxml/entity_registry_spec.rb'
15
+ - 'spec/moxml/allocation_benchmark_spec.rb'
16
+ - 'spec/moxml/allocation_guard_spec.rb'
18
17
 
19
- # Offense count: 1
18
+ # Offense count: 14
20
19
  # This cop supports safe autocorrection (--autocorrect).
21
20
  # Configuration parameters: EnforcedStyleAlignWith.
22
21
  # SupportedStylesAlignWith: either, start_of_block, start_of_line
23
22
  Layout/BlockAlignment:
24
23
  Exclude:
25
- - 'spec/moxml/config_spec.rb'
24
+ - 'lib/moxml/adapter/ox.rb'
25
+ - 'spec/moxml/allocation_benchmark_spec.rb'
26
+ - 'spec/moxml/allocation_guard_spec.rb'
27
+ - 'spec/moxml/lazy_parse_spec.rb'
28
+ - 'spec/moxml/node_cache_spec.rb'
26
29
 
27
- # Offense count: 1
30
+ # Offense count: 7
28
31
  # This cop supports safe autocorrection (--autocorrect).
29
32
  Layout/BlockEndNewline:
30
33
  Exclude:
31
- - 'spec/moxml/config_spec.rb'
34
+ - 'lib/moxml/adapter/ox.rb'
35
+ - 'spec/moxml/allocation_benchmark_spec.rb'
36
+ - 'spec/moxml/allocation_guard_spec.rb'
37
+ - 'spec/moxml/lazy_parse_spec.rb'
38
+ - 'spec/moxml/node_cache_spec.rb'
32
39
 
33
- # Offense count: 1
40
+ # Offense count: 3
34
41
  # This cop supports safe autocorrection (--autocorrect).
35
42
  Layout/ClosingParenthesisIndentation:
36
43
  Exclude:
37
- - 'spec/moxml/entity_registry_spec.rb'
44
+ - 'spec/moxml/allocation_guard_spec.rb'
38
45
 
39
- # Offense count: 1
40
- # This cop supports safe autocorrection (--autocorrect).
41
- Layout/EmptyLineAfterGuardClause:
42
- Exclude:
43
- - 'lib/moxml/config.rb'
44
-
45
- # Offense count: 1
46
+ # Offense count: 3
46
47
  # This cop supports safe autocorrection (--autocorrect).
47
48
  # Configuration parameters: EnforcedStyle, IndentationWidth.
48
49
  # SupportedStyles: consistent, consistent_relative_to_receiver, special_for_inner_method_call, special_for_inner_method_call_in_parentheses
49
50
  Layout/FirstArgumentIndentation:
50
51
  Exclude:
51
- - 'spec/moxml/entity_registry_spec.rb'
52
-
53
- # Offense count: 2
54
- # This cop supports safe autocorrection (--autocorrect).
55
- # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
56
- # SupportedHashRocketStyles: key, separator, table
57
- # SupportedColonStyles: key, separator, table
58
- # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
59
- Layout/HashAlignment:
60
- Exclude:
61
- - 'spec/moxml/entity_registry_spec.rb'
52
+ - 'spec/moxml/allocation_guard_spec.rb'
62
53
 
63
- # Offense count: 2
54
+ # Offense count: 13
64
55
  # This cop supports safe autocorrection (--autocorrect).
65
56
  # Configuration parameters: Width, EnforcedStyleAlignWith, AllowedPatterns.
66
57
  # SupportedStylesAlignWith: start_of_line, relative_to_receiver
67
58
  Layout/IndentationWidth:
68
59
  Exclude:
69
- - 'spec/moxml/config_spec.rb'
60
+ - 'lib/moxml/adapter/ox.rb'
61
+ - 'spec/moxml/allocation_benchmark_spec.rb'
62
+ - 'spec/moxml/allocation_guard_spec.rb'
63
+ - 'spec/moxml/lazy_parse_spec.rb'
64
+ - 'spec/moxml/node_cache_spec.rb'
70
65
 
71
- # Offense count: 238
66
+ # Offense count: 307
72
67
  # This cop supports safe autocorrection (--autocorrect).
73
68
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, AllowRBSInlineAnnotation, AllowCopDirectives, AllowedPatterns, SplitStrings.
74
69
  # URISchemes: http, https
75
70
  Layout/LineLength:
76
71
  Enabled: false
77
72
 
78
- # Offense count: 1
73
+ # Offense count: 3
74
+ # This cop supports safe autocorrection (--autocorrect).
75
+ Layout/MultilineBlockLayout:
76
+ Exclude:
77
+ - 'spec/moxml/allocation_benchmark_spec.rb'
78
+ - 'spec/moxml/allocation_guard_spec.rb'
79
+
80
+ # Offense count: 3
79
81
  # This cop supports safe autocorrection (--autocorrect).
80
82
  # Configuration parameters: EnforcedStyle.
81
83
  # SupportedStyles: symmetrical, new_line, same_line
82
84
  Layout/MultilineMethodCallBraceLayout:
83
85
  Exclude:
84
- - 'spec/moxml/entity_registry_spec.rb'
86
+ - 'spec/moxml/allocation_guard_spec.rb'
85
87
 
86
- # Offense count: 4
88
+ # Offense count: 3
87
89
  # This cop supports safe autocorrection (--autocorrect).
88
90
  # Configuration parameters: AllowInHeredoc.
89
91
  Layout/TrailingWhitespace:
90
92
  Exclude:
91
- - 'lib/moxml/config.rb'
92
- - 'lib/moxml/entity_registry.rb'
93
- - 'spec/moxml/entity_registry_spec.rb'
93
+ - 'spec/moxml/allocation_benchmark_spec.rb'
94
+ - 'spec/moxml/allocation_guard_spec.rb'
94
95
 
95
96
  # Offense count: 7
96
97
  # Configuration parameters: AllowedMethods.
@@ -100,26 +101,28 @@ Lint/ConstantDefinitionInBlock:
100
101
  - 'spec/moxml/declaration_preservation_spec.rb'
101
102
  - 'spec/moxml/sax_spec.rb'
102
103
 
103
- # Offense count: 6
104
+ # Offense count: 8
104
105
  # Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
105
106
  Lint/DuplicateBranch:
106
107
  Exclude:
107
108
  - 'benchmarks/generate_report.rb'
108
109
  - 'lib/moxml/adapter/customized_libxml/declaration.rb'
109
110
  - 'lib/moxml/adapter/libxml.rb'
111
+ - 'lib/moxml/adapter/ox.rb'
110
112
  - 'lib/moxml/document.rb'
111
113
 
112
- # Offense count: 3
114
+ # Offense count: 4
113
115
  Lint/DuplicateMethods:
114
116
  Exclude:
115
117
  - 'lib/moxml/config.rb'
116
118
  - 'lib/moxml/element.rb'
117
119
  - 'lib/moxml/node.rb'
118
120
 
119
- # Offense count: 2
121
+ # Offense count: 4
120
122
  # Configuration parameters: AllowComments, AllowEmptyLambdas.
121
123
  Lint/EmptyBlock:
122
124
  Exclude:
125
+ - 'spec/moxml/allocation_benchmark_spec.rb'
123
126
  - 'spec/moxml/xpath/axes_spec.rb'
124
127
 
125
128
  # Offense count: 1
@@ -153,7 +156,7 @@ Lint/NoReturnInBeginEndBlocks:
153
156
  Exclude:
154
157
  - 'examples/api_client/api_client.rb'
155
158
 
156
- # Offense count: 97
159
+ # Offense count: 100
157
160
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
158
161
  Metrics/AbcSize:
159
162
  Enabled: false
@@ -169,12 +172,12 @@ Metrics/BlockLength:
169
172
  Metrics/BlockNesting:
170
173
  Max: 4
171
174
 
172
- # Offense count: 65
175
+ # Offense count: 70
173
176
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
174
177
  Metrics/CyclomaticComplexity:
175
178
  Enabled: false
176
179
 
177
- # Offense count: 170
180
+ # Offense count: 182
178
181
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
179
182
  Metrics/MethodLength:
180
183
  Max: 110
@@ -184,11 +187,19 @@ Metrics/MethodLength:
184
187
  Metrics/ParameterLists:
185
188
  Max: 7
186
189
 
187
- # Offense count: 44
190
+ # Offense count: 47
188
191
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
189
192
  Metrics/PerceivedComplexity:
190
193
  Enabled: false
191
194
 
195
+ # Offense count: 2
196
+ # This cop supports unsafe autocorrection (--autocorrect-all).
197
+ # Configuration parameters: EnforcedStyleForLeadingUnderscores.
198
+ # SupportedStylesForLeadingUnderscores: disallowed, required, optional
199
+ Naming/MemoizedInstanceVariableName:
200
+ Exclude:
201
+ - 'lib/moxml/element.rb'
202
+
192
203
  # Offense count: 16
193
204
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
194
205
  # AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
@@ -213,6 +224,33 @@ Naming/PredicateMethod:
213
224
  - 'lib/moxml/config.rb'
214
225
  - 'lib/moxml/xpath/ruby/node.rb'
215
226
 
227
+ # Offense count: 10
228
+ # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
229
+ # SupportedStyles: snake_case, normalcase, non_integer
230
+ # AllowedIdentifiers: TLS1_1, TLS1_2, capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
231
+ Naming/VariableNumber:
232
+ Exclude:
233
+ - 'spec/moxml/allocation_guard_spec.rb'
234
+ - 'spec/support/allocation_helper.rb'
235
+
236
+ # Offense count: 1
237
+ # This cop supports unsafe autocorrection (--autocorrect-all).
238
+ Performance/TimesMap:
239
+ Exclude:
240
+ - 'spec/support/allocation_helper.rb'
241
+
242
+ # Offense count: 5
243
+ RSpec/BeforeAfterAll:
244
+ Exclude:
245
+ - '**/spec/spec_helper.rb'
246
+ - '**/spec/rails_helper.rb'
247
+ - '**/spec/support/**/*.rb'
248
+ - 'spec/moxml/allocation_benchmark_spec.rb'
249
+ - 'spec/moxml/allocation_guard_spec.rb'
250
+ - 'spec/moxml/lazy_parse_spec.rb'
251
+ - 'spec/moxml/node_cache_spec.rb'
252
+ - 'spec/moxml/node_set_cache_spec.rb'
253
+
216
254
  # Offense count: 46
217
255
  # Configuration parameters: Prefixes, AllowedPatterns.
218
256
  # Prefixes: when, with, without
@@ -226,12 +264,12 @@ RSpec/ContextWording:
226
264
  - 'spec/moxml/xpath/parser_spec.rb'
227
265
  - 'spec/performance/benchmark_spec.rb'
228
266
 
229
- # Offense count: 16
267
+ # Offense count: 23
230
268
  # Configuration parameters: IgnoredMetadata.
231
269
  RSpec/DescribeClass:
232
270
  Enabled: false
233
271
 
234
- # Offense count: 233
272
+ # Offense count: 271
235
273
  # Configuration parameters: CountAsOne.
236
274
  RSpec/ExampleLength:
237
275
  Max: 64
@@ -267,11 +305,11 @@ RSpec/LeakyConstantDeclaration:
267
305
  RSpec/MessageSpies:
268
306
  EnforcedStyle: receive
269
307
 
270
- # Offense count: 327
308
+ # Offense count: 356
271
309
  RSpec/MultipleExpectations:
272
310
  Max: 10
273
311
 
274
- # Offense count: 2
312
+ # Offense count: 4
275
313
  # Configuration parameters: AllowSubject.
276
314
  RSpec/MultipleMemoizedHelpers:
277
315
  Max: 7
@@ -333,7 +371,7 @@ Security/Eval:
333
371
  Exclude:
334
372
  - 'spec/moxml/xpath/ruby/generator_spec.rb'
335
373
 
336
- # Offense count: 3
374
+ # Offense count: 11
337
375
  # This cop supports safe autocorrection (--autocorrect).
338
376
  # Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
339
377
  # SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
@@ -342,8 +380,11 @@ Security/Eval:
342
380
  # AllowedMethods: lambda, proc, it
343
381
  Style/BlockDelimiters:
344
382
  Exclude:
345
- - 'spec/moxml/config_spec.rb'
346
- - 'spec/moxml/entity_registry_spec.rb'
383
+ - 'lib/moxml/adapter/ox.rb'
384
+ - 'spec/moxml/allocation_benchmark_spec.rb'
385
+ - 'spec/moxml/allocation_guard_spec.rb'
386
+ - 'spec/moxml/lazy_parse_spec.rb'
387
+ - 'spec/moxml/node_cache_spec.rb'
347
388
 
348
389
  # Offense count: 1
349
390
  Style/DocumentDynamicEvalDefinition:
@@ -356,28 +397,32 @@ Style/EvalWithLocation:
356
397
  Exclude:
357
398
  - 'spec/moxml/xpath/ruby/generator_spec.rb'
358
399
 
359
- # Offense count: 2
400
+ # Offense count: 4
360
401
  # Configuration parameters: MinBranchesCount.
361
402
  Style/HashLikeCase:
362
403
  Exclude:
363
404
  - 'lib/moxml/adapter/customized_rexml/formatter.rb'
405
+ - 'lib/moxml/adapter/ox.rb'
364
406
 
365
407
  # Offense count: 1
366
- Style/MissingRespondToMissing:
408
+ # This cop supports unsafe autocorrection (--autocorrect-all).
409
+ Style/MapToHash:
367
410
  Exclude:
368
- - 'lib/moxml/xpath/ruby/node.rb'
411
+ - 'spec/moxml/node_cache_spec.rb'
369
412
 
370
- # Offense count: 2
371
- # This cop supports safe autocorrection (--autocorrect).
372
- Style/MultilineIfModifier:
413
+ # Offense count: 1
414
+ Style/MissingRespondToMissing:
373
415
  Exclude:
374
- - 'lib/moxml/entity_registry.rb'
416
+ - 'lib/moxml/xpath/ruby/node.rb'
375
417
 
376
418
  # Offense count: 1
377
- # This cop supports safe autocorrection (--autocorrect).
378
- Style/NilLambda:
419
+ # This cop supports unsafe autocorrection (--autocorrect-all).
420
+ # Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
421
+ # SupportedStyles: predicate, comparison
422
+ Style/NumericPredicate:
379
423
  Exclude:
380
- - 'spec/moxml/entity_registry_spec.rb'
424
+ - 'spec/**/*'
425
+ - 'lib/moxml/node_set.rb'
381
426
 
382
427
  # Offense count: 5
383
428
  # Configuration parameters: AllowedClasses.
@@ -395,10 +440,16 @@ Style/OptionalBooleanParameter:
395
440
  - 'lib/moxml/adapter/libxml.rb'
396
441
  - 'lib/moxml/xpath/compiler.rb'
397
442
 
443
+ # Offense count: 1
444
+ # This cop supports unsafe autocorrection (--autocorrect-all).
445
+ Style/SelectByKind:
446
+ Exclude:
447
+ - 'lib/moxml/adapter/ox.rb'
448
+
398
449
  # Offense count: 1
399
450
  # This cop supports safe autocorrection (--autocorrect).
400
- # Configuration parameters: EnforcedStyleForMultiline.
401
- # SupportedStylesForMultiline: comma, consistent_comma, diff_comma, no_comma
402
- Style/TrailingCommaInArguments:
451
+ # Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
452
+ # SupportedStyles: single_quotes, double_quotes
453
+ Style/StringLiterals:
403
454
  Exclude:
404
- - 'lib/moxml/context.rb'
455
+ - 'spec/moxml/lazy_parse_spec.rb'
data/Gemfile CHANGED
@@ -22,6 +22,7 @@ gem "rubocop-performance"
22
22
  gem "rubocop-rake"
23
23
  gem "rubocop-rspec"
24
24
  gem "simplecov", require: false
25
+ gem "stackprof"
25
26
  gem "tempfile"
26
27
 
27
28
  # Needed by get_process_mem on Windows
data/README.adoc CHANGED
@@ -815,25 +815,27 @@ context = Moxml.new do |config|
815
815
  end
816
816
  ----
817
817
 
818
- === Namespace URI validation
818
+ === Namespace validation
819
819
 
820
820
  Moxml validates namespace URIs against
821
- https://www.rfc-editor.org/rfc/rfc3986[RFC 3986] by default, as required by the
822
- https://www.w3.org/TR/xml-names/[W3C Namespaces in XML] specification.
821
+ https://www.rfc-editor.org/rfc/rfc3986[RFC 3986] and namespace prefixes against
822
+ the https://www.w3.org/TR/xml-names/[W3C Namespaces in XML] NCName production
823
+ rules by default.
823
824
 
824
- For documents that use non-standard namespace identifiers, a lenient mode is
825
- available:
825
+ For documents that use non-standard namespace identifiers or prefixes, a lenient
826
+ mode is available:
826
827
 
827
828
  [source,ruby]
828
829
  ----
829
- # Strict mode (default) — rejects invalid URIs per RFC 3986
830
+ # Strict mode (default) — validates URI per RFC 3986 and prefix per NCName rules
830
831
  context = Moxml.new do |config|
831
- config.namespace_uri_mode = :strict
832
+ config.namespace_validation_mode = :strict
832
833
  end
833
834
 
834
- # Lenient mode — accepts any string as a namespace URI
835
+ # Lenient mode — accepts any URI string and defers prefix validation to the
836
+ # underlying XML parser
835
837
  context = Moxml.new do |config|
836
- config.namespace_uri_mode = :lenient
838
+ config.namespace_validation_mode = :lenient
837
839
  end
838
840
  ----
839
841
 
data/Rakefile CHANGED
@@ -36,7 +36,9 @@ namespace :spec do
36
36
  categories = ENV.fetch("CATEGORIES", "").split(",").map(&:strip)
37
37
  abort "Usage: CATEGORIES=metanorma,rfcxml rake spec:consistency:by_category" if categories.empty?
38
38
 
39
- include_filters = categories.map { |c| "--tag fixture_category:#{c}" }.join(" ")
39
+ include_filters = categories.map do |c|
40
+ "--tag fixture_category:#{c}"
41
+ end.join(" ")
40
42
  sh "bundle exec rspec spec/consistency/ --tag round_trip #{include_filters}"
41
43
  end
42
44
  end
@@ -97,19 +97,21 @@ context.config.default_encoding = 'UTF-16'
97
97
 
98
98
  **Default:** `"UTF-8"`
99
99
 
100
- ==== Namespace URI validation mode
100
+ ==== Namespace validation mode
101
101
 
102
- Control how strictly namespace URIs are validated:
102
+ Control how strictly namespace URIs and prefixes are validated:
103
103
 
104
104
  [source,ruby]
105
105
  ----
106
- # Strict mode (default) — validates namespace URIs against RFC 3986
107
- context.config.namespace_uri_mode = :strict
108
- doc = context.parse(xml) # Raises ValidationError for invalid URIs
109
-
110
- # Lenient mode — accepts any string as a namespace URI
111
- context.config.namespace_uri_mode = :lenient
112
- doc = context.parse(xml) # Accepts non-standard namespace URIs
106
+ # Strict mode (default) — validates namespace URIs against RFC 3986 and
107
+ # prefixes against NCName rules
108
+ context.config.namespace_validation_mode = :strict
109
+ doc = context.parse(xml) # Raises ValidationError for invalid URIs/prefixes
110
+
111
+ # Lenient mode — accepts any URI string and defers prefix validation to the
112
+ # underlying XML parser
113
+ context.config.namespace_validation_mode = :lenient
114
+ doc = context.parse(xml) # Accepts non-standard namespace URIs/prefixes
113
115
  ----
114
116
 
115
117
  **Default:** `:strict`
@@ -117,23 +119,24 @@ doc = context.parse(xml) # Accepts non-standard namespace URIs
117
119
  **Modes:**
118
120
 
119
121
  `:strict`:: Validates namespace URIs against the
120
- https://www.rfc-editor.org/rfc/rfc3986[RFC 3986] URI-reference specification, as
121
- required by https://www.w3.org/TR/xml-names/[Namespaces in XML]. Invalid URIs
122
- raise a `Moxml::ValidationError`. This is the recommended mode for
123
- standards-compliant XML processing.
122
+ https://www.rfc-editor.org/rfc/rfc3986[RFC 3986] URI-reference specification and
123
+ namespace prefixes against NCName rules, as required by
124
+ https://www.w3.org/TR/xml-names/[Namespaces in XML]. Invalid values raise a
125
+ `Moxml::ValidationError`. This is the recommended mode for standards-compliant
126
+ XML processing.
124
127
 
125
- `:lenient`:: Accepts any string as a namespace URI, only rejecting strings
126
- containing XML-invalid control characters (`0x00`-`0x08`, `0x0B`, `0x0C`,
127
- `0x0E`-`0x1F`). Use this mode when processing XML documents that use
128
- non-standard namespace identifiers such as URNs or other non-URI strings.
128
+ `:lenient`:: Accepts any string as a namespace URI (only rejecting control
129
+ characters) and defers prefix validation to the underlying XML parser. Use this
130
+ mode when processing XML documents that use non-standard namespace identifiers
131
+ or prefixes (e.g., `xmlns_1.0`).
129
132
 
130
133
  **Example:**
131
134
 
132
135
  [source,ruby]
133
136
  ----
134
- # Process documents with non-standard namespace URIs
137
+ # Process documents with non-standard namespace URIs and prefixes
135
138
  context = Moxml.new do |config|
136
- config.namespace_uri_mode = :lenient
139
+ config.namespace_validation_mode = :lenient
137
140
  end
138
141
 
139
142
  xml = '<root xmlns:ex="not a valid URI but accepted in lenient mode"/>'
@@ -280,18 +280,18 @@ puts all_children.length # => 2
280
280
 
281
281
  By default, Moxml validates namespace URIs against
282
282
  https://www.rfc-editor.org/rfc/rfc3986[RFC 3986] (strict mode). To accept
283
- non-standard namespace identifiers, use lenient mode:
283
+ non-standard namespace identifiers or prefixes, use lenient mode:
284
284
 
285
285
  [source,ruby]
286
286
  ----
287
- # Strict mode (default) — validates URIs per RFC 3986
287
+ # Strict mode (default) — validates URIs per RFC 3986 and prefixes per NCName
288
288
  context = Moxml.new do |config|
289
- config.namespace_uri_mode = :strict
289
+ config.namespace_validation_mode = :strict
290
290
  end
291
291
 
292
- # Lenient mode — accepts any string as namespace URI
292
+ # Lenient mode — accepts any URI string and defers prefix validation to parser
293
293
  context = Moxml.new do |config|
294
- config.namespace_uri_mode = :lenient
294
+ config.namespace_validation_mode = :lenient
295
295
  end
296
296
  ----
297
297
 
@@ -98,7 +98,8 @@ module Moxml
98
98
  create_native_declaration(version, encoding, standalone)
99
99
  end
100
100
 
101
- def create_namespace(element, prefix, uri, namespace_uri_mode: :strict)
101
+ def create_namespace(element, prefix, uri,
102
+ namespace_validation_mode: :strict)
102
103
  if prefix && uri.to_s.empty?
103
104
  raise NamespaceError.new(
104
105
  "Prefixed namespace declaration cannot have an empty URI",
@@ -106,8 +107,12 @@ module Moxml
106
107
  uri: uri,
107
108
  )
108
109
  end
109
- validate_prefix(prefix) if prefix
110
- validate_uri(uri, mode: namespace_uri_mode)
110
+ if namespace_validation_mode == :strict
111
+ validate_prefix(prefix) if prefix
112
+ validate_uri(uri, mode: :strict)
113
+ else
114
+ validate_uri(uri, mode: :lenient)
115
+ end
111
116
  create_native_namespace(element, prefix, uri)
112
117
  end
113
118
 
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moxml
4
+ module Adapter
5
+ module CustomizedLibxml
6
+ class EntityReference
7
+ attr_reader :name
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ end
12
+
13
+ def to_xml
14
+ "&#{@name};"
15
+ end
16
+
17
+ def ==(other)
18
+ other.is_a?(self.class) && @name == other.name
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moxml
4
+ module Adapter
5
+ module CustomizedLibxml
6
+ autoload :Cdata, "moxml/adapter/customized_libxml/cdata"
7
+ autoload :Comment, "moxml/adapter/customized_libxml/comment"
8
+ autoload :Declaration, "moxml/adapter/customized_libxml/declaration"
9
+ autoload :Element, "moxml/adapter/customized_libxml/element"
10
+ autoload :EntityReference,
11
+ "moxml/adapter/customized_libxml/entity_reference"
12
+ autoload :Node, "moxml/adapter/customized_libxml/node"
13
+ autoload :ProcessingInstruction,
14
+ "moxml/adapter/customized_libxml/processing_instruction"
15
+ autoload :Text, "moxml/adapter/customized_libxml/text"
16
+ end
17
+ end
18
+ end
@@ -16,7 +16,7 @@ module Moxml
16
16
  def on_element(element, output)
17
17
  name = element.expanded_name
18
18
 
19
- attrs = ""
19
+ attrs = []
20
20
  element.attributes.each do |attr|
21
21
  attrs << " "
22
22
  on_attribute(attr, attrs)
@@ -28,7 +28,7 @@ module Moxml
28
28
  ">"
29
29
  end
30
30
 
31
- output << "<#{name}#{attrs}#{closing_tag}"
31
+ output << "<#{name}#{attrs.join}#{closing_tag}"
32
32
  end
33
33
 
34
34
  def on_namespace_definition(ns, output)
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moxml
4
+ module Adapter
5
+ module CustomizedOga
6
+ autoload :XmlDeclaration, "moxml/adapter/customized_oga/xml_declaration"
7
+ autoload :XmlGenerator, "moxml/adapter/customized_oga/xml_generator"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moxml
4
+ module Adapter
5
+ module CustomizedOx
6
+ class EntityReference
7
+ attr_reader :name
8
+ attr_accessor :parent
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ @parent = nil
13
+ end
14
+
15
+ def to_xml
16
+ "&#{@name};"
17
+ end
18
+
19
+ def ==(other)
20
+ other.is_a?(self.class) && @name == other.name
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moxml
4
+ module Adapter
5
+ module CustomizedOx
6
+ autoload :Attribute, "moxml/adapter/customized_ox/attribute"
7
+ autoload :EntityReference, "moxml/adapter/customized_ox/entity_reference"
8
+ autoload :Namespace, "moxml/adapter/customized_ox/namespace"
9
+ autoload :Text, "moxml/adapter/customized_ox/text"
10
+ end
11
+ end
12
+ end