xml-mapping 0.8.1 → 0.9.1
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.
- data/ChangeLog +64 -3
- data/README +871 -173
- data/README_XPATH +40 -13
- data/Rakefile +37 -26
- data/TODO.txt +39 -8
- data/examples/README +5 -0
- data/examples/company_usage.intout +34 -22
- data/examples/documents_folders.rb +31 -0
- data/examples/documents_folders.xml +16 -0
- data/examples/documents_folders_usage.intin.rb +18 -0
- data/examples/documents_folders_usage.intout +46 -0
- data/examples/order_signature_enhanced_usage.intout +21 -11
- data/examples/order_usage.intin.rb +52 -5
- data/examples/order_usage.intout +154 -80
- data/examples/person.intin.rb +44 -0
- data/examples/person.intout +27 -0
- data/examples/person_mm.intin.rb +119 -0
- data/examples/person_mm.intout +114 -0
- data/examples/publication.intin.rb +44 -0
- data/examples/publication.intout +20 -0
- data/examples/reader.intin.rb +33 -0
- data/examples/reader.intout +19 -0
- data/examples/stringarray.rb +5 -0
- data/examples/stringarray.xml +10 -0
- data/examples/stringarray_usage.intin.rb +11 -0
- data/examples/stringarray_usage.intout +31 -0
- data/examples/time_augm.intout +19 -7
- data/examples/time_augm_loading.intin.rb +44 -0
- data/examples/time_augm_loading.intout +12 -0
- data/examples/time_node.intin.rb +79 -0
- data/examples/time_node.rb +3 -2
- data/examples/time_node_w_marshallers.intin.rb +48 -0
- data/examples/time_node_w_marshallers.intout +25 -0
- data/examples/time_node_w_marshallers.xml +9 -0
- data/examples/xpath_create_new.intout +132 -114
- data/examples/xpath_ensure_created.intout +86 -65
- data/examples/xpath_pathological.intout +16 -16
- data/examples/xpath_usage.intout +1 -1
- data/install.rb +1 -0
- data/lib/xml/mapping.rb +3 -1
- data/lib/xml/mapping/base.rb +442 -272
- data/lib/xml/mapping/core_classes_mapping.rb +32 -0
- data/lib/xml/mapping/standard_nodes.rb +176 -86
- data/lib/xml/mapping/version.rb +2 -2
- data/lib/xml/rexml_ext.rb +186 -0
- data/lib/xml/xxpath.rb +28 -265
- data/lib/xml/xxpath/steps.rb +345 -0
- data/lib/xml/xxpath_methods.rb +96 -0
- data/test/all_tests.rb +4 -1
- data/test/benchmark_fixtures.rb +14 -0
- data/test/{multiple_mappings.rb → bookmarks.rb} +0 -0
- data/test/company.rb +47 -0
- data/test/documents_folders.rb +11 -1
- data/test/examples_test.rb +29 -0
- data/test/fixtures/benchmark.xml +77 -0
- data/test/fixtures/company1.xml +9 -0
- data/test/fixtures/documents_folders.xml +0 -8
- data/test/fixtures/documents_folders2.xml +13 -19
- data/test/fixtures/triangle_m1.xml +17 -0
- data/test/fixtures/triangle_m2.xml +19 -0
- data/test/inheritance_test.rb +50 -0
- data/test/multiple_mappings_test.rb +155 -0
- data/test/rexml_xpath_benchmark.rb +29 -0
- data/test/triangle_mm.rb +57 -0
- data/test/xml_mapping_adv_test.rb +36 -1
- data/test/xml_mapping_test.rb +136 -7
- data/test/xpath_test.rb +154 -0
- data/test/xxpath_benchmark.rb +36 -0
- data/test/xxpath_benchmark.result1.txt +17 -0
- data/test/xxpath_methods_test.rb +61 -0
- metadata +139 -90
data/README_XPATH
CHANGED
@@ -8,12 +8,18 @@ uses xml-xxpath extensively for implementing its node types -- see the
|
|
8
8
|
README file and the reference documentation (and the source code) for
|
9
9
|
details. xml-xxpath, however, does not depend on xml-mapping at all,
|
10
10
|
and is useful in its own right -- maybe I'll later distribute it as a
|
11
|
-
seperate library instead of bundling it.
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
seperate library instead of bundling it. For the time being, if you
|
12
|
+
want to use this XPath implementation stand-alone, you can just rip
|
13
|
+
the files <tt>lib/xml/xxpath.rb</tt>,
|
14
|
+
<tt>lib/xml/xxpath/steps.rb</tt>, and
|
15
|
+
<tt>lib/xml/xxpath_methods.rb</tt> out of the xml-mapping distribution
|
16
|
+
and use them on their own (they do not depend on anything else).
|
17
|
+
|
18
|
+
xml-xxpath's XPath support is vastly incomplete (see below), but, in
|
19
|
+
addition to the normal reading/matching functionality found in other
|
20
|
+
XPath implementations (i.e. "find all elements in a given XML document
|
21
|
+
matching a given XPath expression"), xml-xxpath supports <i>write
|
22
|
+
access</i>. For example, when writing the XPath expression
|
17
23
|
"/foo/bar[3]/baz[@key='hiho']" to the XML document
|
18
24
|
|
19
25
|
<foo>
|
@@ -40,14 +46,13 @@ of the existing XPath implementations, e.g. the one that comes with
|
|
40
46
|
REXML. Also, the whole xml-xxpath implementation is just 300 lines of
|
41
47
|
Ruby code, it is quite fast (paths are precompiled), and xml-xxpath
|
42
48
|
returns matched elements in the order they appeared in the source
|
43
|
-
document -- I've heard REXML::
|
49
|
+
document -- I've heard REXML::XPath doesn't do that :)
|
44
50
|
|
45
|
-
Some basic knowledge of XPath is helpful for reading this document
|
46
|
-
don't know very much either).
|
51
|
+
Some basic knowledge of XPath is helpful for reading this document.
|
47
52
|
|
48
53
|
At the moment, xml-xxpath understands XPath expressions of the form
|
49
|
-
[<tt>/</tt>]_pathelement_<tt
|
50
|
-
each _pathelement_ must be one of these:
|
54
|
+
[<tt>/</tt>]_pathelement_<tt>/[/]</tt>_pathelement_<tt>/[/]</tt>...,
|
55
|
+
where each _pathelement_ must be one of these:
|
51
56
|
|
52
57
|
- a simple element name _name_, e.g. +signature+
|
53
58
|
|
@@ -60,6 +65,23 @@ each _pathelement_ must be one of these:
|
|
60
65
|
|
61
66
|
- the "match-all" path element, <tt>*</tt>
|
62
67
|
|
68
|
+
- .
|
69
|
+
|
70
|
+
- name1|name2|...
|
71
|
+
|
72
|
+
- .[@key='xy'] / self::*[@key='xy']
|
73
|
+
|
74
|
+
- child::*[@key='xy']
|
75
|
+
|
76
|
+
- text()
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
Xml-xxpath only supports relative paths at this time, i.e. XPath
|
81
|
+
expressions beginning with "/" or "//" will still only find nodes
|
82
|
+
below the node the expression is applied to (as if you had written
|
83
|
+
"./" or ".//", respectively).
|
84
|
+
|
63
85
|
|
64
86
|
== Usage
|
65
87
|
|
@@ -115,7 +137,7 @@ against the +firstelt+ element in the example *must not* start with
|
|
115
137
|
|
116
138
|
=== Write Access
|
117
139
|
|
118
|
-
You may pass
|
140
|
+
You may pass an <tt>:ensure_created=>true</tt> option argument to
|
119
141
|
_path_.first(_elt_)/_path_.all(_elt_) calls to make sure that _path_
|
120
142
|
exists inside the passed XML element _elt_. If it existed before,
|
121
143
|
nothing changes, and the call behaves just as it would without the
|
@@ -141,13 +163,18 @@ Examples:
|
|
141
163
|
Alternatively, you may pass a <tt>:create_new=>true</tt> option
|
142
164
|
argument or call <tt>create_new</tt> (_path_.create_new(_elt_) is
|
143
165
|
equivalent to _path_.first(_elt_,:create_new=>true)). In that case, a
|
144
|
-
new node
|
166
|
+
new node is created in _elt_ for each path element of _path_ (or an
|
145
167
|
exception raised if that wasn't possible for any path element).
|
146
168
|
|
147
169
|
Examples:
|
148
170
|
|
149
171
|
:include: xpath_create_new.intout
|
150
172
|
|
173
|
+
This feature is used in xml-mapping by node types like
|
174
|
+
XML::Mapping::ArrayNode, which must create a new instance of the
|
175
|
+
"per-array element path" for each element of the array to be stored in
|
176
|
+
an XML tree.
|
177
|
+
|
151
178
|
|
152
179
|
=== Pathological Cases
|
153
180
|
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
# adapted from active_record's Rakefile
|
3
3
|
|
4
|
+
require 'build_lib/rdoc_ext'
|
5
|
+
|
4
6
|
require 'rubygems'
|
5
7
|
require 'rake'
|
6
8
|
require 'rake/testtask'
|
7
|
-
require '
|
9
|
+
require 'build_lib/my_rdoctask'
|
8
10
|
require 'rake/packagetask'
|
9
11
|
require 'rake/gempackagetask'
|
10
12
|
#require 'rake/contrib/rubyforgepublisher'
|
@@ -12,13 +14,8 @@ require 'rake/contrib/sshpublisher'
|
|
12
14
|
|
13
15
|
require File.dirname(__FILE__)+"/lib/xml/mapping/version"
|
14
16
|
|
15
|
-
|
16
17
|
# yeah -- it's just stupid that these are private
|
17
18
|
|
18
|
-
class Rake::RDocTask
|
19
|
-
public :rdoc_target
|
20
|
-
end
|
21
|
-
|
22
19
|
class Rake::PackageTask
|
23
20
|
public :tgz_file, :zip_file
|
24
21
|
end
|
@@ -28,18 +25,33 @@ class Rake::GemPackageTask
|
|
28
25
|
end
|
29
26
|
|
30
27
|
|
31
|
-
FILES_RDOC_EXTRA=%w{README README_XPATH TODO.txt doc/xpath_impl_notes.txt}
|
28
|
+
FILES_RDOC_EXTRA=%w{README README_XPATH ChangeLog TODO.txt doc/xpath_impl_notes.txt}
|
32
29
|
FILES_RDOC_INCLUDES=%w{examples/company.xml
|
33
30
|
examples/company.rb
|
34
31
|
examples/company_usage.intout
|
32
|
+
examples/order.xml
|
33
|
+
examples/order.rb
|
35
34
|
examples/order_usage.intout
|
35
|
+
examples/stringarray_usage.intout
|
36
|
+
examples/stringarray.xml
|
37
|
+
examples/documents_folders_usage.intout
|
38
|
+
examples/documents_folders.xml
|
39
|
+
examples/time_node_w_marshallers.intout
|
40
|
+
examples/time_node_w_marshallers.xml
|
36
41
|
examples/time_augm.intout
|
42
|
+
examples/time_augm_loading.intout
|
37
43
|
examples/xpath_usage.intout
|
38
44
|
examples/xpath_ensure_created.intout
|
39
45
|
examples/xpath_create_new.intout
|
40
46
|
examples/xpath_pathological.intout
|
41
47
|
examples/xpath_docvsroot.intout
|
42
|
-
examples/order_signature_enhanced_usage.intout
|
48
|
+
examples/order_signature_enhanced_usage.intout
|
49
|
+
examples/order_signature_enhanced.xml
|
50
|
+
examples/person.intout
|
51
|
+
examples/publication.intout
|
52
|
+
examples/reader.intout
|
53
|
+
examples/person_mm.intout
|
54
|
+
}
|
43
55
|
|
44
56
|
|
45
57
|
desc "Default Task"
|
@@ -48,6 +60,7 @@ task :default => [ :test ]
|
|
48
60
|
Rake::TestTask.new(:test) { |t|
|
49
61
|
t.test_files = ["test/all_tests.rb"]
|
50
62
|
t.verbose = true
|
63
|
+
# t.loader = :testrb
|
51
64
|
}
|
52
65
|
|
53
66
|
# runs tests only if sources have changed since last succesful run of
|
@@ -59,10 +72,10 @@ end
|
|
59
72
|
|
60
73
|
|
61
74
|
|
62
|
-
|
75
|
+
MyRDocTask.new { |rdoc|
|
63
76
|
rdoc.rdoc_dir = 'doc/api'
|
64
77
|
rdoc.title = "XML::Mapping -- Simple, extensible Ruby-to-XML (and back) mapper"
|
65
|
-
rdoc.options
|
78
|
+
rdoc.options += %w{--line-numbers --inline-source --accessor cattr_accessor=object --include examples}
|
66
79
|
rdoc.rdoc_files.include(*FILES_RDOC_EXTRA)
|
67
80
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
68
81
|
|
@@ -139,20 +152,17 @@ end
|
|
139
152
|
|
140
153
|
# have to add additional prerequisites manually because it appears
|
141
154
|
# that rules can only define a single prerequisite :-\
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
examples/time_augm
|
146
|
-
examples/xpath_usage
|
147
|
-
examples/xpath_ensure_created
|
148
|
-
examples/xpath_create_new
|
149
|
-
examples/xpath_pathological
|
150
|
-
examples/xpath_docvsroot} do
|
151
|
-
file "#{f}.intout" => ["#{f}.intin.rb", 'examples/company.xml']
|
152
|
-
file "#{f}.intout" => FileList.new("lib/**/*.rb")
|
153
|
-
file "#{f}.intout" => FileList.new("examples/**/*.rb")
|
155
|
+
FILES_RDOC_INCLUDES.select{|f|f=~/.intout$/}.each do |f|
|
156
|
+
file f => FileList.new("lib/**/*.rb")
|
157
|
+
file f => FileList.new("examples/**/*.rb")
|
154
158
|
end
|
155
159
|
|
160
|
+
file 'examples/company_usage.intout' => ['examples/company.xml']
|
161
|
+
file 'examples/documents_folders_usage.intout' => ['examples/documents_folders.xml']
|
162
|
+
file 'examples/order_signature_enhanced_usage.intout' => ['examples/order_signature_enhanced.xml']
|
163
|
+
file 'examples/order_usage.intout' => ['examples/order.xml']
|
164
|
+
file 'examples/stringarray_usage.intout' => ['examples/stringarray.xml']
|
165
|
+
|
156
166
|
|
157
167
|
spec = Gem::Specification.new do |s|
|
158
168
|
s.name = 'xml-mapping'
|
@@ -168,12 +178,12 @@ spec = Gem::Specification.new do |s|
|
|
168
178
|
s.files += Dir.glob("{lib,examples,test}/**/*").delete_if do |item|
|
169
179
|
item.include?("CVS") || item =~ /~$/
|
170
180
|
end
|
171
|
-
s.files += %w{LICENSE Rakefile
|
181
|
+
s.files += %w{LICENSE Rakefile install.rb}
|
172
182
|
s.extra_rdoc_files = FILES_RDOC_EXTRA
|
173
183
|
s.rdoc_options += %w{--include examples}
|
174
184
|
|
175
185
|
s.require_path = 'lib'
|
176
|
-
s.autorequire = 'xml/mapping'
|
186
|
+
# s.autorequire = 'xml/mapping'
|
177
187
|
|
178
188
|
# s.add_dependency 'rexml'
|
179
189
|
|
@@ -182,8 +192,9 @@ spec = Gem::Specification.new do |s|
|
|
182
192
|
s.test_file = 'test/all_tests.rb'
|
183
193
|
|
184
194
|
s.author = 'Olaf Klischat'
|
185
|
-
s.email = 'klischat@
|
195
|
+
s.email = 'olaf.klischat@sofd.de'
|
186
196
|
s.homepage = "http://xml-mapping.rubyforge.org"
|
197
|
+
s.rubyforge_project = "xml-mapping"
|
187
198
|
end
|
188
199
|
|
189
200
|
|
@@ -207,7 +218,7 @@ end
|
|
207
218
|
|
208
219
|
|
209
220
|
task :rfpub_rdoc => [:rdoc] do
|
210
|
-
p=Rake::SshDirPublisher.new('
|
221
|
+
p=Rake::SshDirPublisher.new('rubyforge.org',
|
211
222
|
'/var/www/gforge-projects/xml-mapping/',
|
212
223
|
'doc/api')
|
213
224
|
p.upload
|
data/TODO.txt
CHANGED
@@ -1,18 +1,49 @@
|
|
1
|
-
- XML::XXPath:
|
2
|
-
|
3
|
-
|
1
|
+
- XML::XXPath: Write a real XPath parser eventually
|
2
|
+
|
3
|
+
- XML::XXPath: avoid duplicates in path.all(node) result arrays when
|
4
|
+
using the descendants ("//") axis
|
5
|
+
|
6
|
+
- invent an XPath-like language for Ruby object graphs (i.e. a
|
7
|
+
language that is to Ruby object graphs what XPath is to XML
|
8
|
+
trees). Use expressions in that language as a generalization of
|
9
|
+
"attribute names" (e.g. the 1st parameter to single attribute node
|
10
|
+
factory methods). The language could more or less be Ruby itself,
|
11
|
+
but the write support would need some extra work...
|
12
|
+
|
13
|
+
- XML::XXPath:
|
14
|
+
|
15
|
+
- implement .[@attrname] steps
|
16
|
+
|
17
|
+
- returns the context node iff it contains an attrname attribute
|
18
|
+
|
19
|
+
- doesn't work properly in REXML::XPath?
|
20
|
+
|
21
|
+
- implement *[@attrname] steps
|
22
|
+
|
23
|
+
- implement *[@attrname='attrvalue'] steps
|
24
|
+
|
25
|
+
- id/idref support (write support possible?)
|
26
|
+
|
27
|
+
- XML::Mapping: make SubObjectBaseNode a mixin instead of a subclass
|
28
|
+
of SingleAttributeNode ("mapping sub-objects" and "mapping to a
|
29
|
+
single attribute" are orthogonal concepts; inheritance is bad design
|
30
|
+
here)
|
4
31
|
|
5
32
|
- documentation:
|
6
33
|
|
7
34
|
- README:
|
8
35
|
|
9
|
-
-
|
36
|
+
- document/show usage of default_when_xpath_err outside node type
|
37
|
+
implementations
|
38
|
+
|
39
|
+
- README_XPATH:
|
40
|
+
|
41
|
+
- mention new step types, new axes, xml/xpath_methods
|
10
42
|
|
11
|
-
- XML::Mapping: Move @options hash functionality from
|
12
|
-
SingleAttributeNode to Node.
|
13
43
|
|
14
|
-
- XML::Mapping
|
15
|
-
|
44
|
+
- XML::XXPath/XML::Mapping: support for XML namespaces in XML::XXPath
|
45
|
+
(match nodes with specific namespaces only) and XML::Mapping
|
46
|
+
(use_namespace etc.)
|
16
47
|
|
17
48
|
- add streaming input/output to XML::Mapping, i.e. SAX-based input in
|
18
49
|
addition to the current REXML/DOM - based one. Probably won't be
|
data/examples/README
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
This directory contains the example code snippets from the main README
|
2
|
+
file (each time the documentation is regenerated, they're included in
|
3
|
+
the README, executed, and their output is checked for correctness and
|
4
|
+
included in the README as well). So, if you've read the README, you've
|
5
|
+
already seen all the examples from this directory.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
c = Company.load_from_file('company.xml')
|
2
|
-
=> #<Company:
|
2
|
+
=> #<Company:0x7f487635b068 @address=#<Address:0x7f487635a1e0 @zip=10113, @city="Berlin">, @name="ACME inc.", @customers=[#<Customer:0x7f48763584d0 @name="James Kirk", @id="jim">, #<Customer:0x7f4876356d88 @name="Ernie", @id="ernie">, #<Customer:0x7f4876355640 @name="Bert", @id="bert">]>
|
3
3
|
c.name
|
4
4
|
=> "ACME inc."
|
5
5
|
c.customers.size
|
6
6
|
=> 3
|
7
7
|
c.customers[1]
|
8
|
-
=> #<Customer:
|
8
|
+
=> #<Customer:0x7f4876356d88 @name="Ernie", @id="ernie">
|
9
9
|
c.customers[1].name
|
10
10
|
=> "Ernie"
|
11
11
|
c.customers[0].name
|
@@ -13,27 +13,39 @@ c.customers[0].name
|
|
13
13
|
c.customers[0].name = 'James Tiberius Kirk'
|
14
14
|
=> "James Tiberius Kirk"
|
15
15
|
c.customers << Customer.new('cm','Cookie Monster')
|
16
|
-
=> [#<Customer:
|
16
|
+
=> [#<Customer:0x7f48763584d0 @name="James Tiberius Kirk", @id="jim">, #<Customer:0x7f4876356d88 @name="Ernie", @id="ernie">, #<Customer:0x7f4876355640 @name="Bert", @id="bert">, #<Customer:0x7f4876352b48 @name="Cookie Monster", @id="cm">]
|
17
17
|
xml2 = c.save_to_xml
|
18
18
|
=> <company name='ACME inc.'> ... </>
|
19
19
|
xml2.write($stdout,2)
|
20
20
|
<company name='ACME inc.'>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
</
|
39
|
-
</
|
21
|
+
<address>
|
22
|
+
<city>
|
23
|
+
Berlin
|
24
|
+
</city>
|
25
|
+
<zip>
|
26
|
+
10113
|
27
|
+
</zip>
|
28
|
+
</address>
|
29
|
+
<customers>
|
30
|
+
<customer id='69974598795880'>
|
31
|
+
<name>
|
32
|
+
James Tiberius Kirk
|
33
|
+
</name>
|
34
|
+
</customer>
|
35
|
+
<customer id='69974598792900'>
|
36
|
+
<name>
|
37
|
+
Ernie
|
38
|
+
</name>
|
39
|
+
</customer>
|
40
|
+
<customer id='69974598789920'>
|
41
|
+
<name>
|
42
|
+
Bert
|
43
|
+
</name>
|
44
|
+
</customer>
|
45
|
+
<customer id='69974598784420'>
|
46
|
+
<name>
|
47
|
+
Cookie Monster
|
48
|
+
</name>
|
49
|
+
</customer>
|
50
|
+
</customers>
|
51
|
+
</company>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'xml/mapping'
|
2
|
+
|
3
|
+
class Entry
|
4
|
+
include XML::Mapping
|
5
|
+
|
6
|
+
text_node :name, "@name"
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
class Document <Entry
|
11
|
+
include XML::Mapping
|
12
|
+
|
13
|
+
text_node :contents, "contents"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
class Folder <Entry
|
18
|
+
include XML::Mapping
|
19
|
+
|
20
|
+
array_node :entries, "document|folder", :default_value=>[]
|
21
|
+
|
22
|
+
def [](name)
|
23
|
+
entries.select{|e|e.name==name}[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
def append(name,entry)
|
27
|
+
entries << entry
|
28
|
+
entry.name = name
|
29
|
+
entry
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
|
3
|
+
<folder name="home">
|
4
|
+
<document name="plan">
|
5
|
+
<contents> inhale, exhale</contents>
|
6
|
+
</document>
|
7
|
+
|
8
|
+
<folder name="work">
|
9
|
+
<folder name="xml-mapping">
|
10
|
+
<document name="README">
|
11
|
+
<contents>foo bar baz</contents>
|
12
|
+
</document>
|
13
|
+
</folder>
|
14
|
+
</folder>
|
15
|
+
|
16
|
+
</folder>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#:invisible:
|
2
|
+
$:.unshift "../lib"
|
3
|
+
require 'documents_folders' #<=
|
4
|
+
#:visible:
|
5
|
+
|
6
|
+
root = XML::Mapping.load_object_from_file "documents_folders.xml" #<=
|
7
|
+
root.name #<=
|
8
|
+
root.entries #<=
|
9
|
+
|
10
|
+
root.append "etc", Folder.new
|
11
|
+
root["etc"].append "passwd", Document.new
|
12
|
+
root["etc"]["passwd"].contents = "foo:x:2:2:/bin/sh"
|
13
|
+
root["etc"].append "hosts", Document.new
|
14
|
+
root["etc"]["hosts"].contents = "127.0.0.1 localhost"
|
15
|
+
|
16
|
+
xml = root.save_to_xml #<=
|
17
|
+
#:invisible_retval:
|
18
|
+
xml.write $stdout,2
|