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.
- checksums.yaml +4 -4
- data/.github/workflows/dependent-repos.json +5 -0
- data/.github/workflows/dependent-tests.yml +20 -0
- data/.github/workflows/docs.yml +59 -0
- data/.github/workflows/rake.yml +10 -10
- data/.github/workflows/release.yml +5 -3
- data/.gitignore +37 -0
- data/.rubocop.yml +15 -7
- data/.rubocop_todo.yml +224 -43
- data/Gemfile +14 -9
- data/LICENSE.md +6 -2
- data/README.adoc +535 -373
- data/Rakefile +53 -0
- data/benchmarks/.gitignore +6 -0
- data/benchmarks/generate_report.rb +550 -0
- data/docs/Gemfile +13 -0
- data/docs/_config.yml +138 -0
- data/docs/_guides/advanced-features.adoc +87 -0
- data/docs/_guides/development-testing.adoc +165 -0
- data/docs/_guides/index.adoc +51 -0
- data/docs/_guides/modifying-xml.adoc +292 -0
- data/docs/_guides/parsing-xml.adoc +230 -0
- data/docs/_guides/sax-parsing.adoc +603 -0
- data/docs/_guides/working-with-documents.adoc +118 -0
- data/docs/_guides/xml-declaration.adoc +450 -0
- data/docs/_pages/adapter-compatibility.adoc +369 -0
- data/docs/_pages/adapters/headed-ox.adoc +237 -0
- data/docs/_pages/adapters/index.adoc +97 -0
- data/docs/_pages/adapters/libxml.adoc +285 -0
- data/docs/_pages/adapters/nokogiri.adoc +251 -0
- data/docs/_pages/adapters/oga.adoc +291 -0
- data/docs/_pages/adapters/ox.adoc +56 -0
- data/docs/_pages/adapters/rexml.adoc +292 -0
- data/docs/_pages/best-practices.adoc +429 -0
- data/docs/_pages/compatibility.adoc +467 -0
- data/docs/_pages/configuration.adoc +250 -0
- data/docs/_pages/error-handling.adoc +349 -0
- data/docs/_pages/headed-ox-limitations.adoc +574 -0
- data/docs/_pages/headed-ox.adoc +1025 -0
- data/docs/_pages/index.adoc +35 -0
- data/docs/_pages/installation.adoc +140 -0
- data/docs/_pages/node-api-reference.adoc +49 -0
- data/docs/_pages/performance.adoc +35 -0
- data/docs/_pages/quick-start.adoc +243 -0
- data/docs/_pages/thread-safety.adoc +28 -0
- data/docs/_references/document-api.adoc +407 -0
- data/docs/_references/index.adoc +48 -0
- data/docs/_tutorials/basic-usage.adoc +267 -0
- data/docs/_tutorials/builder-pattern.adoc +342 -0
- data/docs/_tutorials/index.adoc +33 -0
- data/docs/_tutorials/namespace-handling.adoc +324 -0
- data/docs/_tutorials/xpath-queries.adoc +358 -0
- data/docs/index.adoc +122 -0
- data/examples/README.md +124 -0
- data/examples/api_client/README.md +424 -0
- data/examples/api_client/api_client.rb +394 -0
- data/examples/api_client/example_response.xml +48 -0
- data/examples/headed_ox_example/README.md +90 -0
- data/examples/headed_ox_example/headed_ox_demo.rb +71 -0
- data/examples/rss_parser/README.md +194 -0
- data/examples/rss_parser/example_feed.xml +93 -0
- data/examples/rss_parser/rss_parser.rb +189 -0
- data/examples/sax_parsing/README.md +50 -0
- data/examples/sax_parsing/data_extractor.rb +75 -0
- data/examples/sax_parsing/example.xml +21 -0
- data/examples/sax_parsing/large_file.rb +78 -0
- data/examples/sax_parsing/simple_parser.rb +55 -0
- data/examples/web_scraper/README.md +352 -0
- data/examples/web_scraper/example_page.html +201 -0
- data/examples/web_scraper/web_scraper.rb +312 -0
- data/lib/moxml/adapter/base.rb +107 -28
- data/lib/moxml/adapter/customized_libxml/cdata.rb +28 -0
- data/lib/moxml/adapter/customized_libxml/comment.rb +24 -0
- data/lib/moxml/adapter/customized_libxml/declaration.rb +85 -0
- data/lib/moxml/adapter/customized_libxml/element.rb +39 -0
- data/lib/moxml/adapter/customized_libxml/node.rb +44 -0
- data/lib/moxml/adapter/customized_libxml/processing_instruction.rb +31 -0
- data/lib/moxml/adapter/customized_libxml/text.rb +27 -0
- data/lib/moxml/adapter/customized_oga/xml_generator.rb +1 -1
- data/lib/moxml/adapter/customized_ox/attribute.rb +28 -1
- data/lib/moxml/adapter/customized_rexml/formatter.rb +13 -8
- data/lib/moxml/adapter/headed_ox.rb +161 -0
- data/lib/moxml/adapter/libxml.rb +1564 -0
- data/lib/moxml/adapter/nokogiri.rb +156 -9
- data/lib/moxml/adapter/oga.rb +190 -15
- data/lib/moxml/adapter/ox.rb +322 -28
- data/lib/moxml/adapter/rexml.rb +157 -28
- data/lib/moxml/adapter.rb +21 -4
- data/lib/moxml/attribute.rb +6 -0
- data/lib/moxml/builder.rb +40 -4
- data/lib/moxml/config.rb +8 -3
- data/lib/moxml/context.rb +57 -2
- data/lib/moxml/declaration.rb +9 -0
- data/lib/moxml/doctype.rb +13 -1
- data/lib/moxml/document.rb +53 -6
- data/lib/moxml/document_builder.rb +34 -5
- data/lib/moxml/element.rb +71 -2
- data/lib/moxml/error.rb +175 -6
- data/lib/moxml/node.rb +155 -4
- data/lib/moxml/node_set.rb +34 -0
- data/lib/moxml/sax/block_handler.rb +194 -0
- data/lib/moxml/sax/element_handler.rb +124 -0
- data/lib/moxml/sax/handler.rb +113 -0
- data/lib/moxml/sax.rb +31 -0
- data/lib/moxml/version.rb +1 -1
- data/lib/moxml/xml_utils/encoder.rb +4 -4
- data/lib/moxml/xml_utils.rb +7 -4
- data/lib/moxml/xpath/ast/node.rb +159 -0
- data/lib/moxml/xpath/cache.rb +91 -0
- data/lib/moxml/xpath/compiler.rb +1770 -0
- data/lib/moxml/xpath/context.rb +26 -0
- data/lib/moxml/xpath/conversion.rb +124 -0
- data/lib/moxml/xpath/engine.rb +52 -0
- data/lib/moxml/xpath/errors.rb +101 -0
- data/lib/moxml/xpath/lexer.rb +304 -0
- data/lib/moxml/xpath/parser.rb +485 -0
- data/lib/moxml/xpath/ruby/generator.rb +269 -0
- data/lib/moxml/xpath/ruby/node.rb +193 -0
- data/lib/moxml/xpath.rb +37 -0
- data/lib/moxml.rb +5 -2
- data/moxml.gemspec +3 -1
- data/old-specs/moxml/adapter/customized_libxml/.gitkeep +6 -0
- data/spec/consistency/README.md +77 -0
- data/spec/{moxml/examples/adapter_spec.rb → consistency/adapter_parity_spec.rb} +4 -4
- data/spec/examples/README.md +75 -0
- data/spec/{support/shared_examples/examples/attribute.rb → examples/attribute_examples_spec.rb} +1 -1
- data/spec/{support/shared_examples/examples/basic_usage.rb → examples/basic_usage_spec.rb} +2 -2
- data/spec/{support/shared_examples/examples/namespace.rb → examples/namespace_examples_spec.rb} +3 -3
- data/spec/{support/shared_examples/examples/readme_examples.rb → examples/readme_examples_spec.rb} +6 -4
- data/spec/{support/shared_examples/examples/xpath.rb → examples/xpath_examples_spec.rb} +10 -6
- data/spec/integration/README.md +71 -0
- data/spec/{moxml/all_with_adapters_spec.rb → integration/all_adapters_spec.rb} +3 -2
- data/spec/integration/headed_ox_integration_spec.rb +326 -0
- data/spec/{support → integration}/shared_examples/edge_cases.rb +37 -10
- data/spec/integration/shared_examples/high_level/.gitkeep +0 -0
- data/spec/{support/shared_examples/context.rb → integration/shared_examples/high_level/context_behavior.rb} +2 -1
- data/spec/{support/shared_examples/integration.rb → integration/shared_examples/integration_workflows.rb} +23 -6
- data/spec/integration/shared_examples/node_wrappers/.gitkeep +0 -0
- data/spec/{support/shared_examples/cdata.rb → integration/shared_examples/node_wrappers/cdata_behavior.rb} +6 -1
- data/spec/{support/shared_examples/comment.rb → integration/shared_examples/node_wrappers/comment_behavior.rb} +2 -1
- data/spec/{support/shared_examples/declaration.rb → integration/shared_examples/node_wrappers/declaration_behavior.rb} +5 -5
- data/spec/{support/shared_examples/doctype.rb → integration/shared_examples/node_wrappers/doctype_behavior.rb} +2 -2
- data/spec/{support/shared_examples/document.rb → integration/shared_examples/node_wrappers/document_behavior.rb} +1 -1
- data/spec/{support/shared_examples/node.rb → integration/shared_examples/node_wrappers/node_behavior.rb} +9 -2
- data/spec/{support/shared_examples/node_set.rb → integration/shared_examples/node_wrappers/node_set_behavior.rb} +1 -18
- data/spec/{support/shared_examples/processing_instruction.rb → integration/shared_examples/node_wrappers/processing_instruction_behavior.rb} +6 -2
- data/spec/moxml/README.md +41 -0
- data/spec/moxml/adapter/.gitkeep +0 -0
- data/spec/moxml/adapter/README.md +61 -0
- data/spec/moxml/adapter/base_spec.rb +27 -0
- data/spec/moxml/adapter/headed_ox_spec.rb +311 -0
- data/spec/moxml/adapter/libxml_spec.rb +14 -0
- data/spec/moxml/adapter/ox_spec.rb +9 -8
- data/spec/moxml/adapter/shared_examples/.gitkeep +0 -0
- data/spec/{support/shared_examples/xml_adapter.rb → moxml/adapter/shared_examples/adapter_contract.rb} +39 -12
- data/spec/moxml/adapter_spec.rb +16 -0
- data/spec/moxml/attribute_spec.rb +30 -0
- data/spec/moxml/builder_spec.rb +33 -0
- data/spec/moxml/cdata_spec.rb +31 -0
- data/spec/moxml/comment_spec.rb +31 -0
- data/spec/moxml/config_spec.rb +3 -3
- data/spec/moxml/context_spec.rb +28 -0
- data/spec/moxml/declaration_preservation_spec.rb +217 -0
- data/spec/moxml/declaration_spec.rb +36 -0
- data/spec/moxml/doctype_spec.rb +33 -0
- data/spec/moxml/document_builder_spec.rb +30 -0
- data/spec/moxml/document_spec.rb +105 -0
- data/spec/moxml/element_spec.rb +143 -0
- data/spec/moxml/error_spec.rb +266 -22
- data/spec/{moxml_spec.rb → moxml/moxml_spec.rb} +9 -9
- data/spec/moxml/namespace_spec.rb +32 -0
- data/spec/moxml/node_set_spec.rb +39 -0
- data/spec/moxml/node_spec.rb +37 -0
- data/spec/moxml/processing_instruction_spec.rb +34 -0
- data/spec/moxml/sax_spec.rb +1067 -0
- data/spec/moxml/text_spec.rb +31 -0
- data/spec/moxml/version_spec.rb +14 -0
- data/spec/moxml/xml_utils/.gitkeep +0 -0
- data/spec/moxml/xml_utils/encoder_spec.rb +27 -0
- data/spec/moxml/xml_utils_spec.rb +49 -0
- data/spec/moxml/xpath/ast/node_spec.rb +83 -0
- data/spec/moxml/xpath/axes_spec.rb +296 -0
- data/spec/moxml/xpath/cache_spec.rb +358 -0
- data/spec/moxml/xpath/compiler_spec.rb +406 -0
- data/spec/moxml/xpath/context_spec.rb +210 -0
- data/spec/moxml/xpath/conversion_spec.rb +365 -0
- data/spec/moxml/xpath/fixtures/sample.xml +25 -0
- data/spec/moxml/xpath/functions/boolean_functions_spec.rb +114 -0
- data/spec/moxml/xpath/functions/node_functions_spec.rb +145 -0
- data/spec/moxml/xpath/functions/numeric_functions_spec.rb +164 -0
- data/spec/moxml/xpath/functions/position_functions_spec.rb +93 -0
- data/spec/moxml/xpath/functions/special_functions_spec.rb +89 -0
- data/spec/moxml/xpath/functions/string_functions_spec.rb +381 -0
- data/spec/moxml/xpath/lexer_spec.rb +488 -0
- data/spec/moxml/xpath/parser_integration_spec.rb +210 -0
- data/spec/moxml/xpath/parser_spec.rb +364 -0
- data/spec/moxml/xpath/ruby/generator_spec.rb +421 -0
- data/spec/moxml/xpath/ruby/node_spec.rb +291 -0
- data/spec/moxml/xpath_capabilities_spec.rb +199 -0
- data/spec/moxml/xpath_spec.rb +77 -0
- data/spec/performance/README.md +83 -0
- data/spec/performance/benchmark_spec.rb +64 -0
- data/spec/{support/shared_examples/examples/memory.rb → performance/memory_usage_spec.rb} +4 -1
- data/spec/{support/shared_examples/examples/thread_safety.rb → performance/thread_safety_spec.rb} +3 -1
- data/spec/performance/xpath_benchmark_spec.rb +259 -0
- data/spec/spec_helper.rb +58 -1
- data/spec/support/xml_matchers.rb +1 -1
- metadata +178 -34
- data/spec/support/shared_examples/examples/benchmark_spec.rb +0 -51
- /data/spec/{support/shared_examples/builder.rb → integration/shared_examples/high_level/builder_behavior.rb} +0 -0
- /data/spec/{support/shared_examples/document_builder.rb → integration/shared_examples/high_level/document_builder_behavior.rb} +0 -0
- /data/spec/{support/shared_examples/attribute.rb → integration/shared_examples/node_wrappers/attribute_behavior.rb} +0 -0
- /data/spec/{support/shared_examples/element.rb → integration/shared_examples/node_wrappers/element_behavior.rb} +0 -0
- /data/spec/{support/shared_examples/namespace.rb → integration/shared_examples/node_wrappers/namespace_behavior.rb} +0 -0
- /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
|