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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f1290755cf60610b63b7c82a4d043e662627a0c1b7a5692a70e987ddae69fa6
4
- data.tar.gz: 05c9430233444a7915cb36789af8ebad99bc34391324c010a8e9c07f1cd36d33
3
+ metadata.gz: 07caeff68b2413d8ccaab1e827b151c4b98381f76b0f1feb63cec118be54ae05
4
+ data.tar.gz: 76e3eb23022b6d49e5c265467966d29d6ad12617f2a00af3b34680b32f96b8ac
5
5
  SHA512:
6
- metadata.gz: ca2bf23c9b78a09dc984a974b86eadabddca8e4f90dbcdda263ff2295a61a4a6c1252fdeb5ad7ace732533887abef1d8636f5e1c6556f720485ed61d8e93da32
7
- data.tar.gz: 508e707c528f5a729dea7de4a5940a6df8f70a3bd537295ef510a1280be322833b06bdc3b4242f869dae11c7cda09b07b84a9e13ead7f5810fb90f6f565e872c
6
+ metadata.gz: e0a41270e30bca0664d5e4bf32019d82a262cbfe6c2d001879d8e6259bf06e80a24df2372698ecd651835e88b27be2b7f2552b0d26aaf40aa514de7a870bf5e8
7
+ data.tar.gz: 7ade8a4b671b3eb3fe06d2b909783f61bd5172d1645e3c1e9c6344d3e3fb01b5b1c32b8da09b39fedc2b73d04e52edb19956bf00240fbb145798f4be9c598058
data/.rubocop_todo.yml CHANGED
@@ -1,23 +1,24 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2025-11-24 02:45:12 UTC using RuboCop version 1.80.0.
3
+ # on 2025-11-26 03:06:16 UTC using RuboCop version 1.80.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: 179
9
+ # Offense count: 203
10
10
  # This cop supports safe autocorrection (--autocorrect).
11
11
  # Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
12
12
  # URISchemes: http, https
13
13
  Layout/LineLength:
14
14
  Enabled: false
15
15
 
16
- # Offense count: 6
16
+ # Offense count: 7
17
17
  # Configuration parameters: AllowedMethods.
18
18
  # AllowedMethods: enums
19
19
  Lint/ConstantDefinitionInBlock:
20
20
  Exclude:
21
+ - 'spec/moxml/declaration_preservation_spec.rb'
21
22
  - 'spec/moxml/sax_spec.rb'
22
23
 
23
24
  # Offense count: 6
@@ -59,7 +60,7 @@ Lint/NoReturnInBeginEndBlocks:
59
60
  Exclude:
60
61
  - 'examples/api_client/api_client.rb'
61
62
 
62
- # Offense count: 86
63
+ # Offense count: 93
63
64
  # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
64
65
  Metrics/AbcSize:
65
66
  Enabled: false
@@ -75,12 +76,12 @@ Metrics/BlockLength:
75
76
  Metrics/BlockNesting:
76
77
  Max: 4
77
78
 
78
- # Offense count: 57
79
+ # Offense count: 63
79
80
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
80
81
  Metrics/CyclomaticComplexity:
81
82
  Enabled: false
82
83
 
83
- # Offense count: 157
84
+ # Offense count: 164
84
85
  # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
85
86
  Metrics/MethodLength:
86
87
  Max: 110
@@ -90,23 +91,10 @@ Metrics/MethodLength:
90
91
  Metrics/ParameterLists:
91
92
  Max: 7
92
93
 
93
- # Offense count: 36
94
+ # Offense count: 43
94
95
  # Configuration parameters: AllowedMethods, AllowedPatterns, Max.
95
96
  Metrics/PerceivedComplexity:
96
- Exclude:
97
- - 'benchmarks/generate_report.rb'
98
- - 'examples/web_scraper/web_scraper.rb'
99
- - 'lib/moxml/adapter/customized_oga/xml_generator.rb'
100
- - 'lib/moxml/adapter/customized_rexml/formatter.rb'
101
- - 'lib/moxml/adapter/libxml.rb'
102
- - 'lib/moxml/adapter/ox.rb'
103
- - 'lib/moxml/adapter/rexml.rb'
104
- - 'lib/moxml/document.rb'
105
- - 'lib/moxml/xpath/compiler.rb'
106
- - 'lib/moxml/xpath/conversion.rb'
107
- - 'lib/moxml/xpath/lexer.rb'
108
- - 'lib/moxml/xpath/parser.rb'
109
- - 'lib/moxml/xpath/ruby/generator.rb'
97
+ Enabled: false
110
98
 
111
99
  # Offense count: 15
112
100
  # Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
@@ -130,14 +118,7 @@ Naming/PredicateMethod:
130
118
  Exclude:
131
119
  - 'lib/moxml/xpath/ruby/node.rb'
132
120
 
133
- # Offense count: 1
134
- # This cop supports unsafe autocorrection (--autocorrect-all).
135
- # Configuration parameters: OnlySumOrWithInitialValue.
136
- Performance/Sum:
137
- Exclude:
138
- - 'lib/moxml/xpath/compiler.rb'
139
-
140
- # Offense count: 42
121
+ # Offense count: 46
141
122
  # Configuration parameters: Prefixes, AllowedPatterns.
142
123
  # Prefixes: when, with, without
143
124
  RSpec/ContextWording:
@@ -145,11 +126,12 @@ RSpec/ContextWording:
145
126
  - 'spec/integration/headed_ox_integration_spec.rb'
146
127
  - 'spec/moxml/adapter/headed_ox_spec.rb'
147
128
  - 'spec/moxml/adapter/shared_examples/adapter_contract.rb'
129
+ - 'spec/moxml/declaration_preservation_spec.rb'
148
130
  - 'spec/moxml/xpath/lexer_spec.rb'
149
131
  - 'spec/moxml/xpath/parser_spec.rb'
150
132
  - 'spec/performance/benchmark_spec.rb'
151
133
 
152
- # Offense count: 14
134
+ # Offense count: 15
153
135
  # Configuration parameters: IgnoredMetadata.
154
136
  RSpec/DescribeClass:
155
137
  Exclude:
@@ -161,6 +143,7 @@ RSpec/DescribeClass:
161
143
  - 'spec/consistency/adapter_parity_spec.rb'
162
144
  - 'spec/integration/all_adapters_spec.rb'
163
145
  - 'spec/integration/headed_ox_integration_spec.rb'
146
+ - 'spec/moxml/declaration_preservation_spec.rb'
164
147
  - 'spec/moxml/error_spec.rb'
165
148
  - 'spec/moxml/xpath/axes_spec.rb'
166
149
  - 'spec/moxml/xpath/functions/boolean_functions_spec.rb'
@@ -173,7 +156,7 @@ RSpec/DescribeClass:
173
156
  - 'spec/moxml/xpath_capabilities_spec.rb'
174
157
  - 'spec/performance/xpath_benchmark_spec.rb'
175
158
 
176
- # Offense count: 215
159
+ # Offense count: 217
177
160
  # Configuration parameters: CountAsOne.
178
161
  RSpec/ExampleLength:
179
162
  Max: 85
@@ -197,9 +180,10 @@ RSpec/InstanceVariable:
197
180
  Exclude:
198
181
  - 'spec/moxml/sax_spec.rb'
199
182
 
200
- # Offense count: 6
183
+ # Offense count: 7
201
184
  RSpec/LeakyConstantDeclaration:
202
185
  Exclude:
186
+ - 'spec/moxml/declaration_preservation_spec.rb'
203
187
  - 'spec/moxml/sax_spec.rb'
204
188
 
205
189
  # Offense count: 2
@@ -208,7 +192,7 @@ RSpec/LeakyConstantDeclaration:
208
192
  RSpec/MessageSpies:
209
193
  EnforcedStyle: receive
210
194
 
211
- # Offense count: 308
195
+ # Offense count: 317
212
196
  RSpec/MultipleExpectations:
213
197
  Max: 10
214
198
 
@@ -217,6 +201,11 @@ RSpec/MultipleExpectations:
217
201
  RSpec/MultipleMemoizedHelpers:
218
202
  Max: 7
219
203
 
204
+ # Offense count: 10
205
+ # Configuration parameters: AllowedGroups.
206
+ RSpec/NestedGroups:
207
+ Max: 4
208
+
220
209
  # Offense count: 3
221
210
  # Configuration parameters: AllowedPatterns.
222
211
  # AllowedPatterns: ^expect_, ^assert_
@@ -262,12 +251,6 @@ Security/Eval:
262
251
  Exclude:
263
252
  - 'spec/moxml/xpath/ruby/generator_spec.rb'
264
253
 
265
- # Offense count: 1
266
- # This cop supports unsafe autocorrection (--autocorrect-all).
267
- Style/CombinableLoops:
268
- Exclude:
269
- - 'lib/moxml/adapter/customized_rexml/formatter.rb'
270
-
271
254
  # Offense count: 1
272
255
  Style/DocumentDynamicEvalDefinition:
273
256
  Exclude:
data/README.adoc CHANGED
@@ -26,6 +26,8 @@ Key features:
26
26
 
27
27
  == Supported XML libraries
28
28
 
29
+ === General
30
+
29
31
  Moxml supports the following XML libraries:
30
32
 
31
33
  REXML:: https://github.com/ruby/rexml[REXML], a pure Ruby XML parser
@@ -110,7 +112,9 @@ section.
110
112
  NOTE: HeadedOx provides full XPath 1.0 support via a pure Ruby XPath engine
111
113
  layered on top of Ox's C parser. See HeadedOx documentation for details.
112
114
 
113
- NOTE: Ox/HeadedOx SAX: Only core events supported (start_element, end_element, characters, errors). No separate CDATA, comment, or processing instruction events.
115
+ NOTE: Ox/HeadedOx SAX: Only core events supported (start_element, end_element,
116
+ characters, errors). No separate CDATA, comment, or processing instruction
117
+ events.
114
118
 
115
119
  == Adapter comparison
116
120
 
@@ -356,7 +360,7 @@ NOTE: Ox/HeadedOx SAX: Only core events supported (start_element, end_element, c
356
360
  | ✅ Full
357
361
  | ✅ Full
358
362
  | ✅ Full
359
- | ⚠️ Limited^4^
363
+ | Full
360
364
  | ✅ Full
361
365
  | ✅ Full
362
366
 
@@ -400,13 +404,12 @@ NOTE: Ox/HeadedOx SAX: Only core events supported (start_element, end_element, c
400
404
  | ✅ Yes
401
405
  | ✅ Yes
402
406
  |===
403
-
407
+ +
404
408
  ^1^ Ox/HeadedOx: Text node replacement may fail in some cases due to internal node structure +
405
409
  ^2^ Ox: `//book[@id]` works (returns all book elements), but doesn't filter by attribute existence +
406
410
  ^3^ HeadedOx: Full XPath 1.0 with all 27 functions and 6 axes. Pure Ruby XPath engine on Ox's C parser. 99.20% pass rate. See link:docs/headed-ox.adoc[] +
407
411
  ^4^ Ox: Use `.find { |el| el["id"] == "123" }` instead of XPath attribute value predicates +
408
- ^5^ LibXML: DOCTYPE parsing works, serialization is limited (no round-trip preservation) +
409
- ^6^ HeadedOx limitations: Namespace introspection and 7 axes not implemented. See link:docs/HEADED_OX_LIMITATIONS.md[]
412
+ ^5^ HeadedOx limitations: Namespace introspection and 7 axes not implemented. See link:docs/HEADED_OX_LIMITATIONS.md[]
410
413
 
411
414
  === Adapter selection guide
412
415
 
@@ -453,10 +456,13 @@ NOTE: Ox/HeadedOx SAX: Only core events supported (start_element, end_element, c
453
456
  * Need more XPath capabilities than standard Ox provides
454
457
  * Memory efficiency is important but XPath features are required
455
458
 
456
- CAUTION: Ox's custom XPath engine supports common patterns but may not handle
459
+ CAUTION: Ox's custom XPath engine supports common patterns but cannot handle
457
460
  complex XPath expressions. Test thoroughly if your use case requires advanced
458
461
  XPath.
459
462
 
463
+ TODO: We should throw errors when unsupported XPath features are used with Ox
464
+ or HeadedOx to prevent silent failures.
465
+
460
466
 
461
467
  == Getting started
462
468
 
@@ -643,6 +649,23 @@ For complete SAX documentation including all handler types, event methods, adapt
643
649
 
644
650
  For complete node API reference including traversal methods, manipulation, queries, type checking, and node information, see link:docs/_pages/node-api-reference.adoc[Node API Reference].
645
651
 
652
+ === Node identity
653
+
654
+ Moxml provides a consistent `#identifier` method across all node types to safely identify nodes:
655
+
656
+ [source,ruby]
657
+ ----
658
+ element = doc.at_xpath("//book")
659
+ puts element.identifier # => "book"
660
+
661
+ attr = element.attribute("id")
662
+ puts attr.identifier # => "id"
663
+ ----
664
+
665
+ The `#identifier` method returns the primary identifier for each node type (tag name for elements, attribute name for attributes, target for processing instructions, or `nil` for content nodes).
666
+
667
+ IMPORTANT: Always use type-safe patterns when working with mixed node types. See the link:docs/_guides/node-api-consistency.adoc[Node API Consistency Guide] for complete documentation on safe coding patterns, API surface by node type, and migration guidelines.
668
+
646
669
 
647
670
  == Advanced features
648
671
 
@@ -694,7 +717,8 @@ rescue Moxml::Error => e
694
717
  end
695
718
  ----
696
719
 
697
- For complete error class hierarchy, error types, best practices, and debugging techniques, see link:docs/_pages/error-handling.adoc[Error Handling Guide].
720
+ For complete error class hierarchy, error types, best practices, and debugging
721
+ techniques, see link:docs/_pages/error-handling.adoc[Error Handling Guide].
698
722
 
699
723
 
700
724
  == Configuration
@@ -717,22 +741,31 @@ context = Moxml.new do |config|
717
741
  end
718
742
  ----
719
743
 
720
- For all configuration options, adapter selection, serialization options, and environment-based configuration, see link:docs/_pages/configuration.adoc[Configuration Guide].
744
+ For all configuration options, adapter selection, serialization options, and
745
+ environment-based configuration, see
746
+ link:docs/_pages/configuration.adoc[Configuration Guide].
721
747
 
722
748
 
723
749
 
724
750
  == Thread safety
725
751
 
726
- For complete information on thread-safe patterns, context management, and concurrent processing, see the link:docs/_pages/thread-safety.adoc[Thread Safety Guide].
752
+ For complete information on thread-safe patterns, context management, and
753
+ concurrent processing, see the link:docs/_pages/thread-safety.adoc[Thread Safety
754
+ Guide].
727
755
 
728
756
 
729
757
  == Performance considerations
730
758
 
731
- For detailed performance optimization strategies, memory management best practices, and efficient querying patterns, see the link:docs/_pages/performance.adoc[Performance Considerations Guide].
759
+ For detailed performance optimization strategies, memory management best
760
+ practices, and efficient querying patterns, see the
761
+ link:docs/_pages/performance.adoc[Performance Considerations Guide].
732
762
 
733
763
  == Best practices
734
764
 
735
- For comprehensive best practices covering XPath queries, adapter selection, error handling, namespace handling, memory management, thread safety, performance optimization, and testing strategies, see link:docs/_pages/best-practices.adoc[Best Practices Guide].
765
+ For comprehensive best practices covering XPath queries, adapter selection,
766
+ error handling, namespace handling, memory management, thread safety,
767
+ performance optimization, and testing strategies, see
768
+ link:docs/_pages/best-practices.adoc[Best Practices Guide].
736
769
 
737
770
 
738
771
  == Specific adapter limitations
@@ -756,11 +789,13 @@ The Ox adapter provides maximum parsing speed but has XPath limitations.
756
789
  doc.xpath("//book").find { |book| book["id"] == "123" }
757
790
  ----
758
791
 
759
- For complete Ox adapter documentation including all limitations and workarounds, see link:docs/_pages/adapters/ox.adoc[Ox Adapter Guide].
792
+ For complete Ox adapter documentation including all limitations and workarounds,
793
+ see link:docs/_pages/adapters/ox.adoc[Ox Adapter Guide].
760
794
 
761
795
  === HeadedOx adapter
762
796
 
763
- The HeadedOx adapter combines Ox's fast C-based XML parsing with Moxml's comprehensive pure Ruby XPath 1.0 engine.
797
+ The HeadedOx adapter combines Ox's fast C-based XML parsing with Moxml's
798
+ comprehensive pure Ruby XPath 1.0 engine.
764
799
 
765
800
  **Status:** Production-ready v1.2 (99.20% pass rate, 1,992/2,008 tests)
766
801
 
@@ -796,12 +831,6 @@ For complete HeadedOx documentation including architecture, XPath capabilities,
796
831
 
797
832
  ==== LibXML adapter
798
833
 
799
- *DOCTYPE Limitations:*
800
-
801
- * DOCTYPE parsing works
802
- * DOCTYPE round-trip preservation is limited
803
- * DOCTYPE cannot be reliably re-serialized after parsing
804
-
805
834
  *Performance:*
806
835
 
807
836
  * Serialization speed: ~120 ips (slower than target)
@@ -819,7 +848,9 @@ limitations. Use these adapters when you need full XPath and namespace support.
819
848
 
820
849
  == Development and testing
821
850
 
822
- For complete information on development setup, testing strategies, benchmarking, and coverage reporting, see the link:docs/_guides/development-testing.adoc[Development and Testing Guide].
851
+ For complete information on development setup, testing strategies, benchmarking,
852
+ and coverage reporting, see the
853
+ link:docs/_guides/development-testing.adoc[Development and Testing Guide].
823
854
 
824
855
  == Contributing
825
856
 
data/docs/_config.yml CHANGED
@@ -1,9 +1,9 @@
1
1
  # Site settings
2
- title: Moxml
2
+ title: "Moxml: Modern XML for Ruby"
3
3
  description: >-
4
4
  Modern XML processing for Ruby with unified adapter interface
5
5
  baseurl: "/moxml"
6
- url: "https://lutaml.github.io"
6
+ url: "https://www.lutaml.org"
7
7
 
8
8
  # Theme
9
9
  theme: just-the-docs
@@ -43,7 +43,7 @@ back_to_top_text: "Back to top"
43
43
  # Footer content
44
44
  footer_content: >-
45
45
  Copyright © 2025 Ribose. Distributed by a
46
- <a href="https://github.com/lutaml/moxml/blob/main/LICENSE.md">BSD-2-Clause license</a>.
46
+ <a href="https://github.com/lutaml/moxml/blob/main/LICENSE.md">BSD-3-Clause license</a>.
47
47
 
48
48
  # Footer last edit timestamp
49
49
  last_edit_timestamp: true
@@ -10,17 +10,25 @@ Task-oriented guides for common XML processing operations with Moxml.
10
10
  === Document operations
11
11
 
12
12
  link:parsing-xml[Parsing XML]::
13
- Parse XML from strings, files, and IO streams with different adapters.
13
+ Parse XML from strings, files, and IO streams
14
14
 
15
- link:creating-documents[Creating documents]::
16
- Build XML documents from scratch using the builder pattern or direct
17
- manipulation.
15
+ link:working-with-documents[Working with Documents]::
16
+ Create and manipulate XML documents
18
17
 
19
18
  link:modifying-xml[Modifying XML]::
20
- Add, remove, and modify elements, attributes, and content in XML documents.
19
+ Edit elements, attributes, and content
21
20
 
22
- link:serializing-xml[Serializing XML]::
23
- Convert XML documents to strings with formatting and encoding options.
21
+ link:sax-parsing[SAX Parsing]::
22
+ Memory-efficient event-driven parsing
23
+
24
+ link:advanced-features[Advanced Features]::
25
+ Namespaces, XPath, and more
26
+
27
+ link:node-api-consistency[Node API Consistency]::
28
+ Understanding node types and their APIs
29
+
30
+ link:development-testing[Development & Testing]::
31
+ Contributing to Moxml
24
32
 
25
33
  === Querying and traversal
26
34
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  title: Modifying XML
3
- parent: Overview
4
3
  nav_order: 3
5
4
  ---
6
5