moxml 0.1.8 → 0.1.10

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +22 -39
  3. data/README.adoc +51 -20
  4. data/docs/_config.yml +3 -3
  5. data/docs/_guides/index.adoc +15 -7
  6. data/docs/_guides/modifying-xml.adoc +0 -1
  7. data/docs/_guides/node-api-consistency.adoc +572 -0
  8. data/docs/_guides/parsing-xml.adoc +0 -1
  9. data/docs/_guides/xml-declaration.adoc +450 -0
  10. data/docs/_pages/adapter-compatibility.adoc +1 -1
  11. data/docs/_pages/adapters/headed-ox.adoc +9 -9
  12. data/docs/_pages/adapters/index.adoc +0 -1
  13. data/docs/_pages/adapters/libxml.adoc +1 -2
  14. data/docs/_pages/adapters/nokogiri.adoc +1 -2
  15. data/docs/_pages/adapters/oga.adoc +1 -2
  16. data/docs/_pages/adapters/ox.adoc +2 -1
  17. data/docs/_pages/adapters/rexml.adoc +2 -3
  18. data/docs/_pages/best-practices.adoc +0 -1
  19. data/docs/_pages/compatibility.adoc +0 -1
  20. data/docs/_pages/configuration.adoc +0 -1
  21. data/docs/_pages/error-handling.adoc +0 -1
  22. data/docs/_pages/headed-ox-limitations.adoc +16 -0
  23. data/docs/_pages/installation.adoc +0 -1
  24. data/docs/_pages/node-api-reference.adoc +93 -4
  25. data/docs/_pages/performance.adoc +0 -1
  26. data/docs/_pages/quick-start.adoc +0 -1
  27. data/docs/_pages/thread-safety.adoc +0 -1
  28. data/docs/_references/document-api.adoc +0 -1
  29. data/docs/_tutorials/basic-usage.adoc +0 -1
  30. data/docs/_tutorials/builder-pattern.adoc +0 -1
  31. data/docs/_tutorials/namespace-handling.adoc +0 -1
  32. data/docs/_tutorials/xpath-queries.adoc +0 -1
  33. data/lib/moxml/adapter/customized_rexml/formatter.rb +2 -2
  34. data/lib/moxml/adapter/libxml.rb +34 -4
  35. data/lib/moxml/adapter/nokogiri.rb +50 -2
  36. data/lib/moxml/adapter/oga.rb +80 -3
  37. data/lib/moxml/adapter/ox.rb +70 -7
  38. data/lib/moxml/adapter/rexml.rb +45 -10
  39. data/lib/moxml/attribute.rb +6 -0
  40. data/lib/moxml/context.rb +18 -1
  41. data/lib/moxml/declaration.rb +9 -0
  42. data/lib/moxml/doctype.rb +33 -0
  43. data/lib/moxml/document.rb +14 -0
  44. data/lib/moxml/document_builder.rb +7 -0
  45. data/lib/moxml/element.rb +6 -0
  46. data/lib/moxml/error.rb +5 -5
  47. data/lib/moxml/node.rb +73 -1
  48. data/lib/moxml/processing_instruction.rb +6 -0
  49. data/lib/moxml/version.rb +1 -1
  50. data/lib/moxml/xpath/compiler.rb +2 -0
  51. data/lib/moxml/xpath/errors.rb +1 -1
  52. data/spec/integration/shared_examples/node_wrappers/declaration_behavior.rb +0 -3
  53. data/spec/moxml/declaration_preservation_spec.rb +217 -0
  54. data/spec/moxml/doctype_spec.rb +19 -3
  55. data/spec/performance/memory_usage_spec.rb +3 -2
  56. metadata +5 -3
  57. data/.ruby-version +0 -1
@@ -0,0 +1,572 @@
1
+ = Node API consistency guide
2
+ :toc:
3
+ :toclevels: 3
4
+
5
+ == Overview
6
+
7
+ This guide documents the API surface of all node types in Moxml, providing clear
8
+ expectations for developers about which methods are available on which node
9
+ types.
10
+
11
+ == Node Type Hierarchy
12
+
13
+ [source]
14
+ ----
15
+ Node (abstract base)
16
+ ├── Document
17
+ ├── Element
18
+ ├── Attribute
19
+ ├── Text
20
+ ├── Cdata
21
+ ├── Comment
22
+ ├── ProcessingInstruction
23
+ ├── Declaration
24
+ └── Doctype
25
+ ----
26
+
27
+ == Common Node Methods
28
+
29
+ All node types inherit these methods from `Moxml::Node`:
30
+
31
+ === Document Navigation
32
+
33
+ [cols="1,3,1"]
34
+ |===
35
+ | Method | Description | Always Available?
36
+
37
+ | `#document`
38
+ | Returns the containing document
39
+ | ✅ Yes
40
+
41
+ | `#parent`
42
+ | Returns the parent node
43
+ | ✅ Yes
44
+
45
+ | `#children`
46
+ | Returns a NodeSet of child nodes
47
+ | ✅ Yes (may be empty)
48
+
49
+ | `#next_sibling`
50
+ | Returns the next sibling node
51
+ | ✅ Yes (may be nil)
52
+
53
+ | `#previous_sibling`
54
+ | Returns the previous sibling node
55
+ | ✅ Yes (may be nil)
56
+ |===
57
+
58
+ === Tree Manipulation
59
+
60
+ [cols="1,3,1"]
61
+ |===
62
+ | Method | Description | Always Available?
63
+
64
+ | `#add_child(node)`
65
+ | Adds a child node
66
+ | ✅ Yes
67
+
68
+ | `#add_previous_sibling(node)`
69
+ | Adds a sibling before this node
70
+ | ✅ Yes
71
+
72
+ | `#add_next_sibling(node)`
73
+ | Adds a sibling after this node
74
+ | ✅ Yes
75
+
76
+ | `#remove`
77
+ | Removes this node from the tree
78
+ | ✅ Yes
79
+
80
+ | `#replace(node)`
81
+ | Replaces this node with another
82
+ | ✅ Yes
83
+ |===
84
+
85
+ === Serialization
86
+
87
+ [cols="1,3,1"]
88
+ |===
89
+ | Method | Description | Always Available?
90
+
91
+ | `#to_xml(options = {})`
92
+ | Serializes node to XML string
93
+ | ✅ Yes
94
+
95
+ | `#clone` / `#dup`
96
+ | Creates a deep copy of the node
97
+ | ✅ Yes
98
+ |===
99
+
100
+ === XPath Queries
101
+
102
+ [cols="1,3,1"]
103
+ |===
104
+ | Method | Description | Always Available?
105
+
106
+ | `#xpath(expression, ns = {})`
107
+ | Returns NodeSet matching XPath
108
+ | ✅ Yes (adapter-dependent)
109
+
110
+ | `#at_xpath(expression, ns = {})`
111
+ | Returns first node matching XPath
112
+ | ✅ Yes (adapter-dependent)
113
+ |===
114
+
115
+ === Type Checking
116
+
117
+ [cols="1,3,1"]
118
+ |===
119
+ | Method | Description | Always Available?
120
+
121
+ | `#element?`
122
+ | Returns true if node is an Element
123
+ | ✅ Yes
124
+
125
+ | `#text?`
126
+ | Returns true if node is a Text node
127
+ | ✅ Yes
128
+
129
+ | `#cdata?`
130
+ | Returns true if node is a CDATA section
131
+ | ✅ Yes
132
+
133
+ | `#comment?`
134
+ | Returns true if node is a Comment
135
+ | ✅ Yes
136
+
137
+ | `#processing_instruction?`
138
+ | Returns true if node is a PI
139
+ | ✅ Yes
140
+
141
+ | `#document?`
142
+ | Returns true if node is a Document
143
+ | ✅ Yes
144
+
145
+ | `#declaration?`
146
+ | Returns true if node is a Declaration
147
+ | ✅ Yes
148
+
149
+ | `#doctype?`
150
+ | Returns true if node is a Doctype
151
+ | ✅ Yes
152
+
153
+ | `#attribute?`
154
+ | Returns true if node is an Attribute
155
+ | ✅ Yes
156
+ |===
157
+
158
+ == Node Type-Specific APIs
159
+
160
+ === Document
161
+
162
+ The root document node.
163
+
164
+ ==== Additional Methods
165
+
166
+ [cols="1,3,1"]
167
+ |===
168
+ | Method | Description | Always Available?
169
+
170
+ | `#root`
171
+ | Returns the root element
172
+ | ✅ Yes
173
+
174
+ | `#root=(element)`
175
+ | Sets the root element
176
+ | ✅ Yes
177
+
178
+ | `#encoding`
179
+ | Returns document encoding
180
+ | ✅ Yes
181
+
182
+ | `#create_element(name, content = nil)`
183
+ | Creates a new element
184
+ | ✅ Yes
185
+
186
+ | `#create_text(content)`
187
+ | Creates a new text node
188
+ | ✅ Yes
189
+
190
+ | `#create_comment(content)`
191
+ | Creates a new comment
192
+ | ✅ Yes
193
+
194
+ | `#create_cdata(content)`
195
+ | Creates a new CDATA section
196
+ | ✅ Yes
197
+
198
+ | `#create_processing_instruction(target, content)`
199
+ | Creates a new processing instruction
200
+ | ✅ Yes
201
+
202
+ | `#create_declaration(version, encoding, standalone)`
203
+ | Creates a new XML declaration
204
+ | ✅ Yes (adapter-dependent)
205
+ |===
206
+
207
+ === Element
208
+
209
+ Elements are the primary structural nodes with tag names, attributes, and children.
210
+
211
+ ==== Identity Methods
212
+
213
+ [cols="1,3,1"]
214
+ |===
215
+ | Method | Description | Always Available?
216
+
217
+ | `#name`
218
+ | Returns the element tag name
219
+ | ✅ Yes
220
+
221
+ | `#name=(value)`
222
+ | Sets the element tag name
223
+ | ✅ Yes
224
+
225
+ | `#identifier`
226
+ | Returns the primary identifier (same as #name)
227
+ | ✅ Yes
228
+ |===
229
+
230
+ ==== Namespace Methods
231
+
232
+ [cols="1,3,1"]
233
+ |===
234
+ | Method | Description | Always Available?
235
+
236
+ | `#namespace`
237
+ | Returns the element's namespace
238
+ | ✅ Yes (may be nil)
239
+
240
+ | `#namespace=(ns_or_hash)`
241
+ | Sets the element's namespace
242
+ | ✅ Yes
243
+
244
+ | `#namespace_prefix`
245
+ | Returns the namespace prefix
246
+ | ✅ Yes (may be nil)
247
+
248
+ | `#namespace_uri`
249
+ | Returns the namespace URI
250
+ | ✅ Yes (may be nil)
251
+
252
+ | `#namespaces`
253
+ | Returns all namespace definitions
254
+ | ✅ Yes
255
+
256
+ | `#add_namespace(prefix, uri)`
257
+ | Adds a namespace definition
258
+ | ✅ Yes
259
+ |===
260
+
261
+ ==== Attribute Methods
262
+
263
+ [cols="1,3,1"]
264
+ |===
265
+ | Method | Description | Always Available?
266
+
267
+ | `#[](name)`
268
+ | Gets attribute value
269
+ | ✅ Yes
270
+
271
+ | `#[]=(name, value)`
272
+ | Sets attribute value
273
+ | ✅ Yes
274
+
275
+ | `#attribute(name)`
276
+ | Returns Attribute object
277
+ | ✅ Yes (may be nil)
278
+
279
+ | `#attributes`
280
+ | Returns array of all attributes
281
+ | ✅ Yes
282
+
283
+ | `#remove_attribute(name)`
284
+ | Removes an attribute
285
+ | ✅ Yes
286
+ |===
287
+
288
+ ==== Content Methods
289
+
290
+ [cols="1,3,1"]
291
+ |===
292
+ | Method | Description | Always Available?
293
+
294
+ | `#text`
295
+ | Returns text content
296
+ | ✅ Yes
297
+
298
+ | `#text=(content)`
299
+ | Sets text content
300
+ | ✅ Yes
301
+
302
+ | `#inner_text`
303
+ | Returns inner text (concatenated)
304
+ | ✅ Yes
305
+
306
+ | `#inner_xml`
307
+ | Returns inner XML as string
308
+ | ✅ Yes
309
+
310
+ | `#inner_xml=(xml)`
311
+ | Sets inner XML from string
312
+ | ✅ Yes
313
+ |===
314
+
315
+ === Attribute
316
+
317
+ Attributes are name-value pairs attached to elements.
318
+
319
+ ==== Identity Methods
320
+
321
+ [cols="1,3,1"]
322
+ |===
323
+ | Method | Description | Always Available?
324
+
325
+ | `#name`
326
+ | Returns the attribute name
327
+ | ✅ Yes
328
+
329
+ | `#name=(new_name)`
330
+ | Sets the attribute name
331
+ | ✅ Yes
332
+
333
+ | `#identifier`
334
+ | Returns the primary identifier (same as #name)
335
+ | ✅ Yes
336
+ |===
337
+
338
+ ==== Value Methods
339
+
340
+ [cols="1,3,1"]
341
+ |===
342
+ | Method | Description | Always Available?
343
+
344
+ | `#value`
345
+ | Returns the attribute value
346
+ | ✅ Yes
347
+
348
+ | `#value=(new_value)`
349
+ | Sets the attribute value
350
+ | ✅ Yes
351
+
352
+ | `#text`
353
+ | Alias for #value (XPath compatibility)
354
+ | ✅ Yes
355
+ |===
356
+
357
+ ==== Relationship Methods
358
+
359
+ [cols="1,3,1"]
360
+ |===
361
+ | Method | Description | Always Available?
362
+
363
+ | `#element`
364
+ | Returns the owning element
365
+ | ✅ Yes
366
+
367
+ | `#namespace`
368
+ | Returns the attribute's namespace
369
+ | ✅ Yes (may be nil)
370
+ |===
371
+
372
+ === Text
373
+
374
+ Text nodes contain character data.
375
+
376
+ ==== Content Methods
377
+
378
+ [cols="1,3,1"]
379
+ |===
380
+ | Method | Description | Always Available?
381
+
382
+ | `#content`
383
+ | Returns the text content
384
+ | ✅ Yes
385
+
386
+ | `#content=(text)`
387
+ | Sets the text content
388
+ | ✅ Yes
389
+
390
+ | `#text`
391
+ | Alias for #content
392
+ | ✅ Yes
393
+ |===
394
+
395
+ ==== Identity Methods
396
+
397
+ [cols="1,3,1"]
398
+ |===
399
+ | Method | Description | Always Available?
400
+
401
+ | `#identifier`
402
+ | Returns nil (content nodes have no identifier)
403
+ | ✅ Yes
404
+ |===
405
+
406
+ === Cdata
407
+
408
+ CDATA sections contain character data that should not be parsed.
409
+
410
+ ==== Content Methods
411
+
412
+ [cols="1,3,1"]
413
+ |===
414
+ | Method | Description | Always Available?
415
+
416
+ | `#content`
417
+ | Returns the CDATA content
418
+ | ✅ Yes
419
+
420
+ | `#content=(text)`
421
+ | Sets the CDATA content
422
+ | ✅ Yes
423
+
424
+ | `#text`
425
+ | Alias for #content
426
+ | ✅ Yes
427
+ |===
428
+
429
+ ==== Identity Methods
430
+
431
+ [cols="1,3,1"]
432
+ |===
433
+ | Method | Description | Always Available?
434
+
435
+ | `#identifier`
436
+ | Returns nil (content nodes have no identifier)
437
+ | ✅ Yes
438
+ |===
439
+
440
+ === Comment
441
+
442
+ Comment nodes contain XML comments.
443
+
444
+ ==== Content Methods
445
+
446
+ [cols="1,3,1"]
447
+ |===
448
+ | Method | Description | Always Available?
449
+
450
+ | `#content`
451
+ | Returns the comment text
452
+ | ✅ Yes
453
+
454
+ | `#content=(text)`
455
+ | Sets the comment text
456
+ | ✅ Yes
457
+
458
+ | `#text`
459
+ | Alias for #content
460
+ | ✅ Yes
461
+ |===
462
+
463
+ ==== Identity Methods
464
+
465
+ [cols="1,3,1"]
466
+ |===
467
+ | Method | Description | Always Available?
468
+
469
+ | `#identifier`
470
+ | Returns nil (content nodes have no identifier)
471
+ | ✅ Yes
472
+ |===
473
+
474
+ === ProcessingInstruction
475
+
476
+ Processing instructions provide directives to applications.
477
+
478
+ ==== Identity Methods
479
+
480
+ [cols="1,3,1"]
481
+ |===
482
+ | Method | Description | Always Available?
483
+
484
+ | `#target`
485
+ | Returns the PI target
486
+ | ✅ Yes
487
+
488
+ | `#target=(new_target)`
489
+ | Sets the PI target
490
+ | ✅ Yes
491
+
492
+ | `#identifier`
493
+ | Returns the primary identifier (same as #target)
494
+ | ✅ Yes
495
+ |===
496
+
497
+ ==== Content Methods
498
+
499
+ [cols="1,3,1"]
500
+ |===
501
+ | Method | Description | Always Available?
502
+
503
+ | `#content`
504
+ | Returns the PI content
505
+ | ✅ Yes
506
+
507
+ | `#content=(new_content)`
508
+ | Sets the PI content
509
+ | ✅ Yes
510
+ |===
511
+
512
+ === Declaration
513
+
514
+ XML declarations specify document metadata.
515
+
516
+ ==== Property Methods
517
+
518
+ [cols="1,3,1"]
519
+ |===
520
+ | Method | Description | Always Available?
521
+
522
+ | `#version`
523
+ | Returns XML version (e.g., "1.0")
524
+ | ✅ Yes
525
+
526
+ | `#version=(new_version)`
527
+ | Sets XML version
528
+ | ✅ Yes
529
+
530
+ | `#encoding`
531
+ | Returns character encoding
532
+ | ✅ Yes (may be nil)
533
+
534
+ | `#encoding=(new_encoding)`
535
+ | Sets character encoding
536
+ | ✅ Yes
537
+
538
+ | `#standalone`
539
+ | Returns standalone status
540
+ | ✅ Yes (may be nil)
541
+
542
+ | `#standalone=(new_standalone)`
543
+ | Sets standalone status
544
+ | ✅ Yes
545
+ |===
546
+
547
+ ==== Identity Methods
548
+
549
+ [cols="1,3,1"]
550
+ |===
551
+ | Method | Description | Always Available?
552
+
553
+ | `#identifier`
554
+ | Returns nil (declarations have no identifier)
555
+ | ✅ Yes
556
+ |===
557
+
558
+ === Doctype
559
+
560
+ Document type declarations specify DTD information.
561
+
562
+ WARNING: Doctype accessor methods are **not fully implemented** across all adapters. The availability of these methods depends on the specific adapter being used.
563
+
564
+ ==== Identity Methods
565
+
566
+ [cols="1,3,1"]
567
+ |===
568
+ |Doctype |`#name` |✅ Yes |Returns DOCTYPE name (root element)
569
+ |Doctype |`#external_id` |✅ Yes |Returns PUBLIC identifier
570
+ |Doctype |`#system_id` |✅ Yes |Returns SYSTEM identifier (DTD URI)
571
+ |Doctype |`#identifier` |✅ Yes |Returns DOCTYPE name (same as `#name`)
572
+ |===
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  title: Parsing XML
3
- parent: Overview
4
3
  nav_order: 2
5
4
  ---
6
5