moxml 0.1.7 → 0.1.9

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