moxml 0.1.6 → 0.1.8

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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/dependent-repos.json +5 -0
  3. data/.github/workflows/dependent-tests.yml +20 -0
  4. data/.github/workflows/docs.yml +59 -0
  5. data/.github/workflows/rake.yml +12 -4
  6. data/.github/workflows/release.yml +5 -3
  7. data/.gitignore +37 -0
  8. data/.rubocop.yml +15 -7
  9. data/.rubocop_todo.yml +238 -40
  10. data/Gemfile +14 -9
  11. data/LICENSE.md +6 -2
  12. data/README.adoc +535 -373
  13. data/Rakefile +53 -0
  14. data/benchmarks/.gitignore +6 -0
  15. data/benchmarks/generate_report.rb +550 -0
  16. data/docs/Gemfile +13 -0
  17. data/docs/_config.yml +138 -0
  18. data/docs/_guides/advanced-features.adoc +87 -0
  19. data/docs/_guides/development-testing.adoc +165 -0
  20. data/docs/_guides/index.adoc +45 -0
  21. data/docs/_guides/modifying-xml.adoc +293 -0
  22. data/docs/_guides/parsing-xml.adoc +231 -0
  23. data/docs/_guides/sax-parsing.adoc +603 -0
  24. data/docs/_guides/working-with-documents.adoc +118 -0
  25. data/docs/_pages/adapter-compatibility.adoc +369 -0
  26. data/docs/_pages/adapters/headed-ox.adoc +237 -0
  27. data/docs/_pages/adapters/index.adoc +98 -0
  28. data/docs/_pages/adapters/libxml.adoc +286 -0
  29. data/docs/_pages/adapters/nokogiri.adoc +252 -0
  30. data/docs/_pages/adapters/oga.adoc +292 -0
  31. data/docs/_pages/adapters/ox.adoc +55 -0
  32. data/docs/_pages/adapters/rexml.adoc +293 -0
  33. data/docs/_pages/best-practices.adoc +430 -0
  34. data/docs/_pages/compatibility.adoc +468 -0
  35. data/docs/_pages/configuration.adoc +251 -0
  36. data/docs/_pages/error-handling.adoc +350 -0
  37. data/docs/_pages/headed-ox-limitations.adoc +558 -0
  38. data/docs/_pages/headed-ox.adoc +1025 -0
  39. data/docs/_pages/index.adoc +35 -0
  40. data/docs/_pages/installation.adoc +141 -0
  41. data/docs/_pages/node-api-reference.adoc +50 -0
  42. data/docs/_pages/performance.adoc +36 -0
  43. data/docs/_pages/quick-start.adoc +244 -0
  44. data/docs/_pages/thread-safety.adoc +29 -0
  45. data/docs/_references/document-api.adoc +408 -0
  46. data/docs/_references/index.adoc +48 -0
  47. data/docs/_tutorials/basic-usage.adoc +268 -0
  48. data/docs/_tutorials/builder-pattern.adoc +343 -0
  49. data/docs/_tutorials/index.adoc +33 -0
  50. data/docs/_tutorials/namespace-handling.adoc +325 -0
  51. data/docs/_tutorials/xpath-queries.adoc +359 -0
  52. data/docs/index.adoc +122 -0
  53. data/examples/README.md +124 -0
  54. data/examples/api_client/README.md +424 -0
  55. data/examples/api_client/api_client.rb +394 -0
  56. data/examples/api_client/example_response.xml +48 -0
  57. data/examples/headed_ox_example/README.md +90 -0
  58. data/examples/headed_ox_example/headed_ox_demo.rb +71 -0
  59. data/examples/rss_parser/README.md +194 -0
  60. data/examples/rss_parser/example_feed.xml +93 -0
  61. data/examples/rss_parser/rss_parser.rb +189 -0
  62. data/examples/sax_parsing/README.md +50 -0
  63. data/examples/sax_parsing/data_extractor.rb +75 -0
  64. data/examples/sax_parsing/example.xml +21 -0
  65. data/examples/sax_parsing/large_file.rb +78 -0
  66. data/examples/sax_parsing/simple_parser.rb +55 -0
  67. data/examples/web_scraper/README.md +352 -0
  68. data/examples/web_scraper/example_page.html +201 -0
  69. data/examples/web_scraper/web_scraper.rb +312 -0
  70. data/lib/moxml/adapter/base.rb +107 -28
  71. data/lib/moxml/adapter/customized_libxml/cdata.rb +28 -0
  72. data/lib/moxml/adapter/customized_libxml/comment.rb +24 -0
  73. data/lib/moxml/adapter/customized_libxml/declaration.rb +85 -0
  74. data/lib/moxml/adapter/customized_libxml/element.rb +39 -0
  75. data/lib/moxml/adapter/customized_libxml/node.rb +44 -0
  76. data/lib/moxml/adapter/customized_libxml/processing_instruction.rb +31 -0
  77. data/lib/moxml/adapter/customized_libxml/text.rb +27 -0
  78. data/lib/moxml/adapter/customized_oga/xml_generator.rb +1 -1
  79. data/lib/moxml/adapter/customized_ox/attribute.rb +28 -3
  80. data/lib/moxml/adapter/customized_ox/namespace.rb +0 -2
  81. data/lib/moxml/adapter/customized_ox/text.rb +0 -2
  82. data/lib/moxml/adapter/customized_rexml/formatter.rb +11 -6
  83. data/lib/moxml/adapter/headed_ox.rb +161 -0
  84. data/lib/moxml/adapter/libxml.rb +1548 -0
  85. data/lib/moxml/adapter/nokogiri.rb +121 -9
  86. data/lib/moxml/adapter/oga.rb +123 -12
  87. data/lib/moxml/adapter/ox.rb +283 -27
  88. data/lib/moxml/adapter/rexml.rb +127 -20
  89. data/lib/moxml/adapter.rb +21 -4
  90. data/lib/moxml/attribute.rb +6 -0
  91. data/lib/moxml/builder.rb +40 -4
  92. data/lib/moxml/config.rb +8 -3
  93. data/lib/moxml/context.rb +39 -1
  94. data/lib/moxml/doctype.rb +13 -1
  95. data/lib/moxml/document.rb +39 -6
  96. data/lib/moxml/document_builder.rb +27 -5
  97. data/lib/moxml/element.rb +71 -2
  98. data/lib/moxml/error.rb +175 -6
  99. data/lib/moxml/node.rb +94 -3
  100. data/lib/moxml/node_set.rb +34 -0
  101. data/lib/moxml/sax/block_handler.rb +194 -0
  102. data/lib/moxml/sax/element_handler.rb +124 -0
  103. data/lib/moxml/sax/handler.rb +113 -0
  104. data/lib/moxml/sax.rb +31 -0
  105. data/lib/moxml/version.rb +1 -1
  106. data/lib/moxml/xml_utils/encoder.rb +4 -4
  107. data/lib/moxml/xml_utils.rb +7 -4
  108. data/lib/moxml/xpath/ast/node.rb +159 -0
  109. data/lib/moxml/xpath/cache.rb +91 -0
  110. data/lib/moxml/xpath/compiler.rb +1768 -0
  111. data/lib/moxml/xpath/context.rb +26 -0
  112. data/lib/moxml/xpath/conversion.rb +124 -0
  113. data/lib/moxml/xpath/engine.rb +52 -0
  114. data/lib/moxml/xpath/errors.rb +101 -0
  115. data/lib/moxml/xpath/lexer.rb +304 -0
  116. data/lib/moxml/xpath/parser.rb +485 -0
  117. data/lib/moxml/xpath/ruby/generator.rb +269 -0
  118. data/lib/moxml/xpath/ruby/node.rb +193 -0
  119. data/lib/moxml/xpath.rb +37 -0
  120. data/lib/moxml.rb +5 -2
  121. data/moxml.gemspec +3 -1
  122. data/old-specs/moxml/adapter/customized_libxml/.gitkeep +6 -0
  123. data/spec/consistency/README.md +77 -0
  124. data/spec/{moxml/examples/adapter_spec.rb → consistency/adapter_parity_spec.rb} +4 -4
  125. data/spec/examples/README.md +75 -0
  126. data/spec/{support/shared_examples/examples/attribute.rb → examples/attribute_examples_spec.rb} +1 -1
  127. data/spec/{support/shared_examples/examples/basic_usage.rb → examples/basic_usage_spec.rb} +2 -2
  128. data/spec/{support/shared_examples/examples/namespace.rb → examples/namespace_examples_spec.rb} +3 -3
  129. data/spec/{support/shared_examples/examples/readme_examples.rb → examples/readme_examples_spec.rb} +6 -4
  130. data/spec/{support/shared_examples/examples/xpath.rb → examples/xpath_examples_spec.rb} +10 -6
  131. data/spec/integration/README.md +71 -0
  132. data/spec/{moxml/all_with_adapters_spec.rb → integration/all_adapters_spec.rb} +3 -2
  133. data/spec/integration/headed_ox_integration_spec.rb +326 -0
  134. data/spec/{support → integration}/shared_examples/edge_cases.rb +37 -10
  135. data/spec/integration/shared_examples/high_level/.gitkeep +0 -0
  136. data/spec/{support/shared_examples/context.rb → integration/shared_examples/high_level/context_behavior.rb} +2 -1
  137. data/spec/{support/shared_examples/integration.rb → integration/shared_examples/integration_workflows.rb} +23 -6
  138. data/spec/integration/shared_examples/node_wrappers/.gitkeep +0 -0
  139. data/spec/{support/shared_examples/cdata.rb → integration/shared_examples/node_wrappers/cdata_behavior.rb} +6 -1
  140. data/spec/{support/shared_examples/comment.rb → integration/shared_examples/node_wrappers/comment_behavior.rb} +2 -1
  141. data/spec/{support/shared_examples/declaration.rb → integration/shared_examples/node_wrappers/declaration_behavior.rb} +5 -2
  142. data/spec/{support/shared_examples/doctype.rb → integration/shared_examples/node_wrappers/doctype_behavior.rb} +2 -2
  143. data/spec/{support/shared_examples/document.rb → integration/shared_examples/node_wrappers/document_behavior.rb} +1 -1
  144. data/spec/{support/shared_examples/node.rb → integration/shared_examples/node_wrappers/node_behavior.rb} +9 -2
  145. data/spec/{support/shared_examples/node_set.rb → integration/shared_examples/node_wrappers/node_set_behavior.rb} +1 -18
  146. data/spec/{support/shared_examples/processing_instruction.rb → integration/shared_examples/node_wrappers/processing_instruction_behavior.rb} +6 -2
  147. data/spec/moxml/README.md +41 -0
  148. data/spec/moxml/adapter/.gitkeep +0 -0
  149. data/spec/moxml/adapter/README.md +61 -0
  150. data/spec/moxml/adapter/base_spec.rb +27 -0
  151. data/spec/moxml/adapter/headed_ox_spec.rb +311 -0
  152. data/spec/moxml/adapter/libxml_spec.rb +14 -0
  153. data/spec/moxml/adapter/ox_spec.rb +9 -8
  154. data/spec/moxml/adapter/shared_examples/.gitkeep +0 -0
  155. data/spec/{support/shared_examples/xml_adapter.rb → moxml/adapter/shared_examples/adapter_contract.rb} +39 -12
  156. data/spec/moxml/adapter_spec.rb +16 -0
  157. data/spec/moxml/attribute_spec.rb +30 -0
  158. data/spec/moxml/builder_spec.rb +33 -0
  159. data/spec/moxml/cdata_spec.rb +31 -0
  160. data/spec/moxml/comment_spec.rb +31 -0
  161. data/spec/moxml/config_spec.rb +3 -3
  162. data/spec/moxml/context_spec.rb +28 -0
  163. data/spec/moxml/declaration_spec.rb +36 -0
  164. data/spec/moxml/doctype_spec.rb +33 -0
  165. data/spec/moxml/document_builder_spec.rb +30 -0
  166. data/spec/moxml/document_spec.rb +105 -0
  167. data/spec/moxml/element_spec.rb +143 -0
  168. data/spec/moxml/error_spec.rb +266 -22
  169. data/spec/{moxml_spec.rb → moxml/moxml_spec.rb} +9 -9
  170. data/spec/moxml/namespace_spec.rb +32 -0
  171. data/spec/moxml/node_set_spec.rb +39 -0
  172. data/spec/moxml/node_spec.rb +37 -0
  173. data/spec/moxml/processing_instruction_spec.rb +34 -0
  174. data/spec/moxml/sax_spec.rb +1067 -0
  175. data/spec/moxml/text_spec.rb +31 -0
  176. data/spec/moxml/version_spec.rb +14 -0
  177. data/spec/moxml/xml_utils/.gitkeep +0 -0
  178. data/spec/moxml/xml_utils/encoder_spec.rb +27 -0
  179. data/spec/moxml/xml_utils_spec.rb +49 -0
  180. data/spec/moxml/xpath/ast/node_spec.rb +83 -0
  181. data/spec/moxml/xpath/axes_spec.rb +296 -0
  182. data/spec/moxml/xpath/cache_spec.rb +358 -0
  183. data/spec/moxml/xpath/compiler_spec.rb +406 -0
  184. data/spec/moxml/xpath/context_spec.rb +210 -0
  185. data/spec/moxml/xpath/conversion_spec.rb +365 -0
  186. data/spec/moxml/xpath/fixtures/sample.xml +25 -0
  187. data/spec/moxml/xpath/functions/boolean_functions_spec.rb +114 -0
  188. data/spec/moxml/xpath/functions/node_functions_spec.rb +145 -0
  189. data/spec/moxml/xpath/functions/numeric_functions_spec.rb +164 -0
  190. data/spec/moxml/xpath/functions/position_functions_spec.rb +93 -0
  191. data/spec/moxml/xpath/functions/special_functions_spec.rb +89 -0
  192. data/spec/moxml/xpath/functions/string_functions_spec.rb +381 -0
  193. data/spec/moxml/xpath/lexer_spec.rb +488 -0
  194. data/spec/moxml/xpath/parser_integration_spec.rb +210 -0
  195. data/spec/moxml/xpath/parser_spec.rb +364 -0
  196. data/spec/moxml/xpath/ruby/generator_spec.rb +421 -0
  197. data/spec/moxml/xpath/ruby/node_spec.rb +291 -0
  198. data/spec/moxml/xpath_capabilities_spec.rb +199 -0
  199. data/spec/moxml/xpath_spec.rb +77 -0
  200. data/spec/performance/README.md +83 -0
  201. data/spec/performance/benchmark_spec.rb +64 -0
  202. data/spec/{support/shared_examples/examples/memory.rb → performance/memory_usage_spec.rb} +3 -1
  203. data/spec/{support/shared_examples/examples/thread_safety.rb → performance/thread_safety_spec.rb} +3 -1
  204. data/spec/performance/xpath_benchmark_spec.rb +259 -0
  205. data/spec/spec_helper.rb +58 -1
  206. data/spec/support/xml_matchers.rb +1 -1
  207. metadata +176 -35
  208. data/lib/ox/node.rb +0 -9
  209. data/spec/support/shared_examples/examples/benchmark_spec.rb +0 -51
  210. /data/spec/{support/shared_examples/builder.rb → integration/shared_examples/high_level/builder_behavior.rb} +0 -0
  211. /data/spec/{support/shared_examples/document_builder.rb → integration/shared_examples/high_level/document_builder_behavior.rb} +0 -0
  212. /data/spec/{support/shared_examples/attribute.rb → integration/shared_examples/node_wrappers/attribute_behavior.rb} +0 -0
  213. /data/spec/{support/shared_examples/element.rb → integration/shared_examples/node_wrappers/element_behavior.rb} +0 -0
  214. /data/spec/{support/shared_examples/namespace.rb → integration/shared_examples/node_wrappers/namespace_behavior.rb} +0 -0
  215. /data/spec/{support/shared_examples/text.rb → integration/shared_examples/node_wrappers/text_behavior.rb} +0 -0
@@ -0,0 +1,408 @@
1
+ ---
2
+ title: Document API
3
+ parent: Overview
4
+ nav_order: 2
5
+ ---
6
+
7
+ == Document API
8
+
9
+ === Purpose
10
+
11
+ Complete reference for the Document class methods and properties.
12
+
13
+ === Class: Moxml::Document
14
+
15
+ The Document class represents an XML document and serves as the root container
16
+ for all XML nodes.
17
+
18
+ === Creating documents
19
+
20
+ [source,ruby]
21
+ ----
22
+ # Parse from XML string
23
+ doc = Moxml.new.parse(xml_string)
24
+
25
+ # Create empty document
26
+ doc = Moxml.new.create_document
27
+
28
+ # Using builder
29
+ doc = Moxml::Builder.build(Moxml.new) do |xml|
30
+ xml.root "content"
31
+ end
32
+ ----
33
+
34
+ === Instance methods
35
+
36
+ ==== `#root`
37
+
38
+ Returns the root element of the document.
39
+
40
+ [source,ruby]
41
+ ----
42
+ doc = Moxml.new.parse('<library><book/></library>')
43
+ root = doc.root
44
+ puts root.name # => "library"
45
+ ----
46
+
47
+ **Returns:** `Moxml::Element` or `nil`
48
+
49
+ ==== `#root=(element)`
50
+
51
+ Sets the root element of the document.
52
+
53
+ [source,ruby]
54
+ ----
55
+ doc = Moxml.new.create_document
56
+ root = doc.create_element('library')
57
+ doc.root = root
58
+ ----
59
+
60
+ **Parameters:**
61
+
62
+ * `element` (`Moxml::Element`) - The element to set as root
63
+
64
+ ==== `#children`
65
+
66
+ Returns all top-level children of the document.
67
+
68
+ [source,ruby]
69
+ ----
70
+ doc = Moxml.new.parse('<?xml version="1.0"?><root/>')
71
+ children = doc.children
72
+ # => [Declaration, Element]
73
+ ----
74
+
75
+ **Returns:** `Moxml::NodeSet`
76
+
77
+ ==== `#add_child(node)`
78
+
79
+ Adds a child node to the document.
80
+
81
+ [source,ruby]
82
+ ----
83
+ doc = Moxml.new.create_document
84
+
85
+ # Add declaration
86
+ decl = doc.create_declaration
87
+ doc.add_child(decl)
88
+
89
+ # Add root element
90
+ root = doc.create_element('library')
91
+ doc.add_child(root)
92
+ ----
93
+
94
+ **Parameters:**
95
+
96
+ * `node` (`Moxml::Node`) - The node to add
97
+
98
+ **Returns:** `Moxml::Node` - The added node
99
+
100
+ ==== `#remove_child(node)`
101
+
102
+ Removes a child node from the document.
103
+
104
+ [source,ruby]
105
+ ----
106
+ doc.remove_child(declaration)
107
+ ----
108
+
109
+ **Parameters:**
110
+
111
+ * `node` (`Moxml::Node`) - The node to remove
112
+
113
+ ==== `#create_element(name)`
114
+
115
+ Creates a new element node.
116
+
117
+ [source,ruby]
118
+ ----
119
+ elem = doc.create_element('book')
120
+ elem.text = 'Content'
121
+ ----
122
+
123
+ **Parameters:**
124
+
125
+ * `name` (`String`) - Element name
126
+
127
+ **Returns:** `Moxml::Element`
128
+
129
+ ==== `#create_text(content)`
130
+
131
+ Creates a new text node.
132
+
133
+ [source,ruby]
134
+ ----
135
+ text = doc.create_text('content')
136
+ element.add_child(text)
137
+ ----
138
+
139
+ **Parameters:**
140
+
141
+ * `content` (`String`) - Text content
142
+
143
+ **Returns:** `Moxml::Text`
144
+
145
+ ==== `#create_comment(content)`
146
+
147
+ Creates a new comment node.
148
+
149
+ [source,ruby]
150
+ ----
151
+ comment = doc.create_comment('Note: this is important')
152
+ element.add_child(comment)
153
+ ----
154
+
155
+ **Parameters:**
156
+
157
+ * `content` (`String`) - Comment text
158
+
159
+ **Returns:** `Moxml::Comment`
160
+
161
+ ==== `#create_cdata(content)`
162
+
163
+ Creates a new CDATA section.
164
+
165
+ [source,ruby]
166
+ ----
167
+ cdata = doc.create_cdata('<raw>HTML content</raw>')
168
+ element.add_child(cdata)
169
+ ----
170
+
171
+ **Parameters:**
172
+
173
+ * `content` (`String`) - CDATA content
174
+
175
+ **Returns:** `Moxml::Cdata`
176
+
177
+ ==== `#create_processing_instruction(target, content)`
178
+
179
+ Creates a new processing instruction.
180
+
181
+ [source,ruby]
182
+ ----
183
+ pi = doc.create_processing_instruction('xml-stylesheet',
184
+ 'type="text/xsl" href="style.xsl"')
185
+ doc.add_child(pi)
186
+ ----
187
+
188
+ **Parameters:**
189
+
190
+ * `target` (`String`) - PI target
191
+ * `content` (`String`) - PI content
192
+
193
+ **Returns:** `Moxml::ProcessingInstruction`
194
+
195
+ ==== `#create_declaration(version, encoding, standalone)`
196
+
197
+ Creates a new XML declaration.
198
+
199
+ [source,ruby]
200
+ ----
201
+ # With defaults
202
+ decl = doc.create_declaration
203
+ # => <?xml version="1.0" encoding="UTF-8"?>
204
+
205
+ # Custom values
206
+ decl = doc.create_declaration("1.1", "ISO-8859-1", "yes")
207
+ # => <?xml version="1.1" encoding="ISO-8859-1" standalone="yes"?>
208
+ ----
209
+
210
+ **Parameters:**
211
+
212
+ * `version` (`String`, optional) - XML version (default: "1.0")
213
+ * `encoding` (`String`, optional) - Character encoding (default: "UTF-8")
214
+ * `standalone` (`String`, optional) - Standalone declaration ("yes"/"no")
215
+
216
+ **Returns:** `Moxml::Declaration`
217
+
218
+ ==== `#create_doctype(name, external_id, system_id)`
219
+
220
+ Creates a new DOCTYPE declaration.
221
+
222
+ [source,ruby]
223
+ ----
224
+ doctype = doc.create_doctype('html')
225
+ doc.add_child(doctype)
226
+
227
+ # With system ID
228
+ doctype = doc.create_doctype('root', nil, 'test.dtd')
229
+ ----
230
+
231
+ **Parameters:**
232
+
233
+ * `name` (`String`) - DOCTYPE name
234
+ * `external_id` (`String`, optional) - External ID
235
+ * `system_id` (`String`, optional) - System ID
236
+
237
+ **Returns:** `Moxml::Doctype`
238
+
239
+ ==== `#xpath(expression, namespaces = {})`
240
+
241
+ Finds nodes matching XPath expression.
242
+
243
+ [source,ruby]
244
+ ----
245
+ books = doc.xpath('//book[@id="1"]')
246
+
247
+ # With namespaces
248
+ ns = { 'dc' => 'http://purl.org/dc/elements/1.1/' }
249
+ titles = doc.xpath('//dc:title', ns)
250
+ ----
251
+
252
+ **Parameters:**
253
+
254
+ * `expression` (`String`) - XPath expression
255
+ * `namespaces` (`Hash`, optional) - Namespace prefix mappings
256
+
257
+ **Returns:** `Moxml::NodeSet`
258
+
259
+ **Raises:** `Moxml::XPathError` if expression is invalid
260
+
261
+ ==== `#at_xpath(expression, namespaces = {})`
262
+
263
+ Finds first node matching XPath expression.
264
+
265
+ [source,ruby]
266
+ ----
267
+ book = doc.at_xpath('//book[@id="1"]')
268
+ ----
269
+
270
+ **Parameters:**
271
+
272
+ * `expression` (`String`) - XPath expression
273
+ * `namespaces` (`Hash`, optional) - Namespace prefix mappings
274
+
275
+ **Returns:** `Moxml::Node` or `nil`
276
+
277
+ **Raises:** `Moxml::XPathError` if expression is invalid
278
+
279
+ ==== `#to_xml(options = {})`
280
+
281
+ Serializes document to XML string.
282
+
283
+ [source,ruby]
284
+ ----
285
+ # Default formatting
286
+ xml = doc.to_xml
287
+
288
+ # With indentation
289
+ xml = doc.to_xml(indent: 2)
290
+
291
+ # Without declaration
292
+ xml = doc.to_xml(no_declaration: true)
293
+
294
+ # Custom encoding
295
+ xml = doc.to_xml(encoding: 'ISO-8859-1')
296
+ ----
297
+
298
+ **Parameters:**
299
+
300
+ * `options` (`Hash`, optional) - Serialization options
301
+ ** `:indent` (`Integer`) - Indentation spaces (default: 0)
302
+ ** `:encoding` (`String`) - Output encoding
303
+ ** `:no_declaration` (`Boolean`) - Omit XML declaration
304
+
305
+ **Returns:** `String` - XML document as string
306
+
307
+ ==== `#declaration`
308
+
309
+ Returns the XML declaration if present.
310
+
311
+ [source,ruby]
312
+ ----
313
+ doc = Moxml.new.parse('<?xml version="1.0"?><root/>')
314
+ decl = doc.declaration
315
+ puts decl.version # => "1.0"
316
+ puts decl.encoding # => nil (not specified)
317
+ ----
318
+
319
+ **Returns:** `Moxml::Declaration` or `nil`
320
+
321
+ ==== `#doctype`
322
+
323
+ Returns the DOCTYPE declaration if present.
324
+
325
+ [source,ruby]
326
+ ----
327
+ doc = Moxml.new.parse('<!DOCTYPE root><root/>')
328
+ doctype = doc.doctype
329
+ puts doctype.name # => "root"
330
+ ----
331
+
332
+ **Returns:** `Moxml::Doctype` or `nil`
333
+
334
+ ==== `#encoding`
335
+
336
+ Gets or sets document encoding.
337
+
338
+ [source,ruby]
339
+ ----
340
+ doc.encoding = 'UTF-8'
341
+ puts doc.encoding # => "UTF-8"
342
+ ----
343
+
344
+ ==== `#version`
345
+
346
+ Gets or sets XML version.
347
+
348
+ [source,ruby]
349
+ ----
350
+ doc.version = '1.0'
351
+ puts doc.version # => "1.0"
352
+ ----
353
+
354
+ ==== `#context`
355
+
356
+ Returns the Moxml context.
357
+
358
+ [source,ruby]
359
+ ----
360
+ context = doc.context
361
+ adapter = context.config.adapter
362
+ ----
363
+
364
+ **Returns:** `Moxml::Context`
365
+
366
+ === Complete example
367
+
368
+ [source,ruby]
369
+ ----
370
+ # Create comprehensive document
371
+ doc = Moxml.new.create_document
372
+
373
+ # Add declaration
374
+ decl = doc.create_declaration("1.0", "UTF-8")
375
+ doc.add_child(decl)
376
+
377
+ # Add doctype
378
+ doctype = doc.create_doctype('library')
379
+ doc.add_child(doctype)
380
+
381
+ # Create root
382
+ root = doc.create_element('library')
383
+ root.add_namespace('dc', 'http://purl.org/dc/elements/1.1/')
384
+ doc.add_child(root)
385
+
386
+ # Add content
387
+ book = doc.create_element('book')
388
+ book['id'] = '1'
389
+
390
+ title = doc.create_element('dc:title')
391
+ title.text = 'Ruby Programming'
392
+ book.add_child(title)
393
+
394
+ root.add_child(book)
395
+
396
+ # Query
397
+ ns = { 'dc' => 'http://purl.org/dc/elements/1.1/' }
398
+ titles = doc.xpath('//dc:title', ns)
399
+
400
+ # Serialize
401
+ puts doc.to_xml(indent: 2)
402
+ ----
403
+
404
+ === See also
405
+
406
+ * link:element-api[Element API] - Element methods
407
+ * link:../pages/quick-start[Quick start] - Basic usage examples
408
+ * link:../guides/creating-documents[Creating documents guide]
@@ -0,0 +1,48 @@
1
+ ---
2
+ title: Overview
3
+ nav_order: 1
4
+ ---
5
+
6
+ == Reference
7
+
8
+ Detailed technical specifications and API documentation for Moxml.
9
+
10
+ === API reference
11
+
12
+ link:document-api[Document API]::
13
+ Complete reference for Document class methods and properties.
14
+
15
+ link:element-api[Element API]::
16
+ Detailed documentation of Element class methods and operations.
17
+
18
+ link:node-api[Node API]::
19
+ Base Node class methods available to all node types.
20
+
21
+ link:node-types[Node types]::
22
+ Reference for Text, Comment, CDATA, ProcessingInstruction, and other node
23
+ types.
24
+
25
+ link:namespace-api[Namespace API]::
26
+ Methods and operations for working with XML namespaces.
27
+
28
+ link:xpath-api[XPath API]::
29
+ XPath query methods, expressions, and namespace handling.
30
+
31
+ === Adapter reference
32
+
33
+ link:adapter-api[Adapter API]::
34
+ Base adapter interface and adapter-specific method documentation.
35
+
36
+ link:adapter-capabilities[Adapter capabilities]::
37
+ Detailed feature matrix and capability comparison across all adapters.
38
+
39
+ === Utilities
40
+
41
+ link:builder-api[Builder API]::
42
+ DSL methods for building XML documents programmatically.
43
+
44
+ link:error-classes[Error classes]::
45
+ Complete reference of all error classes with attributes and usage.
46
+
47
+ link:xml-utils[XML utilities]::
48
+ Validation, encoding, and utility functions.
@@ -0,0 +1,268 @@
1
+ ---
2
+ title: Basic usage
3
+ parent: Overview
4
+ nav_order: 2
5
+ ---
6
+
7
+ == Basic usage
8
+
9
+ === Purpose
10
+
11
+ Learn the fundamentals of XML processing with Moxml through hands-on examples
12
+ covering parsing, creating, querying, and modifying XML documents.
13
+
14
+ === Prerequisites
15
+
16
+ * Moxml installed with an adapter
17
+ * Basic understanding of XML concepts
18
+
19
+ === Step 1: Parse XML documents
20
+
21
+ Start by parsing existing XML:
22
+
23
+ [source,ruby]
24
+ ----
25
+ require 'moxml'
26
+
27
+ # Create a Moxml context
28
+ context = Moxml.new
29
+
30
+ # Parse XML from a string
31
+ xml = '<library><book id="1">Ruby Programming</book></library>'
32
+ doc = context.parse(xml)
33
+
34
+ # Access the root element
35
+ puts doc.root.name # => "library"
36
+
37
+ # Access child elements
38
+ book = doc.root.children.first
39
+ puts book.name # => "book"
40
+ puts book['id'] # => "1"
41
+ puts book.text # => "Ruby Programming"
42
+ ----
43
+
44
+ === Step 2: Query with XPath
45
+
46
+ Use XPath to find elements:
47
+
48
+ [source,ruby]
49
+ ----
50
+ xml = <<~XML
51
+ <library>
52
+ <book id="1" category="programming">
53
+ <title>Ruby Basics</title>
54
+ <author>Jane Smith</author>
55
+ <price>29.99</price>
56
+ </book>
57
+ <book id="2" category="fiction">
58
+ <title>Ruby Story</title>
59
+ <author>John Doe</author>
60
+ <price>19.99</price>
61
+ </book>
62
+ </library>
63
+ XML
64
+
65
+ doc = context.parse(xml)
66
+
67
+ # Find all books
68
+ all_books = doc.xpath('//book')
69
+ puts "Total books: #{all_books.length}" # => 2
70
+
71
+ # Find specific book by attribute
72
+ book1 = doc.at_xpath('//book[@id="1"]')
73
+ puts book1.at_xpath('.//title').text # => "Ruby Basics"
74
+
75
+ # Find all titles
76
+ titles = doc.xpath('//book/title')
77
+ titles.each { |t| puts t.text }
78
+ # => Ruby Basics
79
+ # => Ruby Story
80
+
81
+ # Find books by category
82
+ programming = doc.xpath('//book[@category="programming"]')
83
+ puts programming.first.at_xpath('.//title').text # => "Ruby Basics"
84
+ ----
85
+
86
+ === Step 3: Create XML documents
87
+
88
+ Build XML from scratch using the builder:
89
+
90
+ [source,ruby]
91
+ ----
92
+ doc = Moxml::Builder.build(context) do |xml|
93
+ xml.declaration version: "1.0", encoding: "UTF-8"
94
+
95
+ xml.library do
96
+ xml.book id: "1", category: "programming" do
97
+ xml.title "Ruby Basics"
98
+ xml.author "Jane Smith"
99
+ xml.price "29.99"
100
+ end
101
+ end
102
+ end
103
+
104
+ puts doc.to_xml(indent: 2)
105
+ ----
106
+
107
+ Output:
108
+
109
+ [source,xml]
110
+ ----
111
+ <?xml version="1.0" encoding="UTF-8"?>
112
+ <library>
113
+ <book id="1" category="programming">
114
+ <title>Ruby Basics</title>
115
+ <author>Jane Smith</author>
116
+ <price>29.99</price>
117
+ </book>
118
+ </library>
119
+ ----
120
+
121
+ === Step 4: Modify XML content
122
+
123
+ Update existing XML documents:
124
+
125
+ [source,ruby]
126
+ ----
127
+ xml = '<library><book id="1"><title>Old Title</title></book></library>'
128
+ doc = context.parse(xml)
129
+
130
+ # Find element to modify
131
+ book = doc.at_xpath('//book[@id="1"]')
132
+
133
+ # Update text content
134
+ title = book.at_xpath('.//title')
135
+ title.text = 'New Title'
136
+
137
+ # Update attributes
138
+ book['id'] = '100'
139
+ book['category'] = 'programming'
140
+
141
+ # Add new elements
142
+ author = doc.create_element('author')
143
+ author.text = 'Jane Smith'
144
+ book.add_child(author)
145
+
146
+ # Add price
147
+ price = doc.create_element('price')
148
+ price.text = '29.99'
149
+ book.add_child(price)
150
+
151
+ puts doc.to_xml(indent: 2)
152
+ ----
153
+
154
+ === Step 5: Work with attributes
155
+
156
+ Manage element attributes:
157
+
158
+ [source,ruby]
159
+ ----
160
+ doc = context.parse('<book/>')
161
+ book = doc.root
162
+
163
+ # Set attributes
164
+ book['id'] = '1'
165
+ book['isbn'] = '978-0-123456-78-9'
166
+ book['category'] = 'programming'
167
+
168
+ # Get attributes
169
+ puts book['id'] # => "1"
170
+ puts book['isbn'] # => "978-0-123456-78-9"
171
+
172
+ # Check attribute existence
173
+ has_id = book.attributes.any? { |a| a.name == 'id' }
174
+ puts has_id # => true
175
+
176
+ # Remove attributes
177
+ book.remove_attribute('category')
178
+
179
+ # List all attributes
180
+ book.attributes.each do |attr|
181
+ puts "#{attr.name} = #{attr.value}"
182
+ end
183
+ ----
184
+
185
+ === Step 6: Handle special content
186
+
187
+ Work with CDATA, comments, and processing instructions:
188
+
189
+ [source,ruby]
190
+ ----
191
+ doc = context.create_document
192
+
193
+ root = doc.create_element('data')
194
+ doc.add_child(root)
195
+
196
+ # Add comment
197
+ comment = doc.create_comment('This is a note')
198
+ root.add_child(comment)
199
+
200
+ # Add CDATA section
201
+ cdata = doc.create_cdata('<raw>XML content</raw>')
202
+ root.add_child(cdata)
203
+
204
+ # Add processing instruction
205
+ pi = doc.create_processing_instruction('xml-stylesheet',
206
+ 'type="text/xsl" href="style.xsl"')
207
+ doc.add_child(pi)
208
+
209
+ puts doc.to_xml
210
+ ----
211
+
212
+ Output:
213
+
214
+ [source,xml]
215
+ ----
216
+ <?xml-stylesheet type="text/xsl" href="style.xsl"?>
217
+ <data>
218
+ <!--This is a note-->
219
+ <![CDATA[<raw>XML content</raw>]]>
220
+ </data>
221
+ ----
222
+
223
+ === Step 7: Error handling
224
+
225
+ Handle XML processing errors:
226
+
227
+ [source,ruby]
228
+ ----
229
+ # Handle parse errors
230
+ begin
231
+ doc = context.parse('<invalid><unclosed>', strict: true)
232
+ rescue Moxml::ParseError => e
233
+ puts "Parse error: #{e.message}"
234
+ puts "Hint: #{e.to_s}"
235
+ end
236
+
237
+ # Handle XPath errors
238
+ begin
239
+ doc.xpath('//invalid[[[')
240
+ rescue Moxml::XPathError => e
241
+ puts "Invalid XPath: #{e.expression}"
242
+ end
243
+
244
+ # Handle validation errors
245
+ begin
246
+ doc.version = "invalid"
247
+ rescue Moxml::ValidationError => e
248
+ puts "Validation error: #{e.message}"
249
+ end
250
+ ----
251
+
252
+ === Next steps
253
+
254
+ * link:working-with-elements[Working with elements] - Deep dive into element
255
+ manipulation
256
+ * link:xpath-queries[XPath queries] - Master XPath querying
257
+ * link:namespace-handling[Namespace handling] - Work with XML namespaces
258
+ * link:../guides/[Guides] - Task-oriented documentation
259
+
260
+ === Practice exercises
261
+
262
+ Try these exercises to reinforce your learning:
263
+
264
+ . Parse an XML file from disk and find all elements with a specific attribute
265
+ . Create a new XML document with nested elements and multiple attributes
266
+ . Modify an existing document by adding, updating, and removing elements
267
+ . Query a document using XPath with predicates
268
+ . Handle namespaced XML documents