tilia-xml 1.2.0
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 +7 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +32 -0
- data/.simplecov +4 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.sabre.md +167 -0
- data/CONTRIBUTING.md +25 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +56 -0
- data/LICENSE +27 -0
- data/LICENSE.sabre +27 -0
- data/README.md +30 -0
- data/Rakefile +17 -0
- data/lib/tilia/xml/context_stack_trait.rb +99 -0
- data/lib/tilia/xml/element/base.rb +73 -0
- data/lib/tilia/xml/element/cdata.rb +53 -0
- data/lib/tilia/xml/element/elements.rb +109 -0
- data/lib/tilia/xml/element/key_value.rb +110 -0
- data/lib/tilia/xml/element/uri.rb +98 -0
- data/lib/tilia/xml/element/xml_fragment.rb +128 -0
- data/lib/tilia/xml/element.rb +22 -0
- data/lib/tilia/xml/lib_xml_exception.rb +9 -0
- data/lib/tilia/xml/parse_exception.rb +7 -0
- data/lib/tilia/xml/reader.rb +240 -0
- data/lib/tilia/xml/service.rb +151 -0
- data/lib/tilia/xml/version.rb +9 -0
- data/lib/tilia/xml/writer.rb +261 -0
- data/lib/tilia/xml/xml_deserializable.rb +29 -0
- data/lib/tilia/xml/xml_serializable.rb +27 -0
- data/lib/tilia/xml.rb +23 -0
- data/test/test_helper.rb +4 -0
- data/test/xml/context_stack_test.rb +40 -0
- data/test/xml/element/cdata_test.rb +37 -0
- data/test/xml/element/eater.rb +60 -0
- data/test/xml/element/elements_test.rb +113 -0
- data/test/xml/element/key_value_test.rb +187 -0
- data/test/xml/element/mock.rb +52 -0
- data/test/xml/element/uri_test.rb +55 -0
- data/test/xml/element/xml_fragment_test.rb +121 -0
- data/test/xml/infite_loop_test.rb +47 -0
- data/test/xml/reader_test.rb +407 -0
- data/test/xml/service_test.rb +156 -0
- data/test/xml/writer_test.rb +260 -0
- data/tilia-xml.gemspec +15 -0
- metadata +132 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Tilia
|
2
|
+
module Xml
|
3
|
+
# Objects implementing XmlSerializable can control how they are represented in
|
4
|
+
# Xml.
|
5
|
+
module XmlSerializable
|
6
|
+
# The xmlSerialize metod is called during xml writing.
|
7
|
+
#
|
8
|
+
# Use the $writer argument to write its own xml serialization.
|
9
|
+
#
|
10
|
+
# An important note: do _not_ create a parent element. Any element
|
11
|
+
# implementing XmlSerializble should only ever write what's considered
|
12
|
+
# its 'inner xml'.
|
13
|
+
#
|
14
|
+
# The parent of the current element is responsible for writing a
|
15
|
+
# containing element.
|
16
|
+
#
|
17
|
+
# This allows serializers to be re-used for different element names.
|
18
|
+
#
|
19
|
+
# If you are opening new elements, you must also close them again.
|
20
|
+
#
|
21
|
+
# @param [Writer] _writer
|
22
|
+
# @return [void]
|
23
|
+
def xml_serialize(_writer)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/tilia/xml.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Namespace for Tilia library
|
2
|
+
module Tilia
|
3
|
+
# Load active support core extensions
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_support/core_ext'
|
6
|
+
|
7
|
+
# Tilia libraries
|
8
|
+
require 'tilia/uri'
|
9
|
+
|
10
|
+
# Namespace of the Tilia::Xml library
|
11
|
+
module Xml
|
12
|
+
require 'tilia/xml/xml_deserializable'
|
13
|
+
require 'tilia/xml/xml_serializable'
|
14
|
+
require 'tilia/xml/context_stack_trait'
|
15
|
+
require 'tilia/xml/element'
|
16
|
+
require 'tilia/xml/parse_exception'
|
17
|
+
require 'tilia/xml/lib_xml_exception'
|
18
|
+
require 'tilia/xml/reader'
|
19
|
+
require 'tilia/xml/service'
|
20
|
+
require 'tilia/xml/version'
|
21
|
+
require 'tilia/xml/writer'
|
22
|
+
end
|
23
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
class ContextStackTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@stack = ContextStackMock.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_push_and_pull
|
11
|
+
@stack.context_uri = '/foo/bar'
|
12
|
+
@stack.element_map['{DAV:}foo'] = 'Bar'
|
13
|
+
@stack.namespace_map['DAV:'] = 'd'
|
14
|
+
|
15
|
+
@stack.push_context
|
16
|
+
|
17
|
+
assert_equal('/foo/bar', @stack.context_uri)
|
18
|
+
assert_equal('Bar', @stack.element_map['{DAV:}foo'])
|
19
|
+
assert_equal('d', @stack.namespace_map['DAV:'])
|
20
|
+
|
21
|
+
@stack.context_uri = '/gir/zim'
|
22
|
+
@stack.element_map['{DAV:}foo'] = 'newBar'
|
23
|
+
@stack.namespace_map['DAV:'] = 'dd'
|
24
|
+
|
25
|
+
@stack.pop_context
|
26
|
+
|
27
|
+
assert_equal('/foo/bar', @stack.context_uri)
|
28
|
+
assert_equal('Bar', @stack.element_map['{DAV:}foo'])
|
29
|
+
assert_equal('d', @stack.namespace_map['DAV:'])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ContextStackMock
|
34
|
+
include ContextStackTrait
|
35
|
+
def initialize
|
36
|
+
initialize_context_stack_attributes
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
class CDataTest < Minitest::Test
|
6
|
+
def test_deserialize
|
7
|
+
input = <<BLA
|
8
|
+
<?xml version="1.0"?>
|
9
|
+
<root xmlns="http://sabredav.org/ns">
|
10
|
+
<blabla />
|
11
|
+
</root>
|
12
|
+
BLA
|
13
|
+
reader = Reader.new
|
14
|
+
reader.element_map = { '{http://sabredav.org/ns}blabla' => Element::Cdata }
|
15
|
+
reader.xml(input)
|
16
|
+
assert_raises(RuntimeError) { reader.parse }
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_serialize
|
20
|
+
writer = Writer.new
|
21
|
+
writer.namespace_map = { 'http://sabredav.org/ns' => nil }
|
22
|
+
writer.open_memory
|
23
|
+
writer.start_document
|
24
|
+
writer.set_indent(true)
|
25
|
+
writer.write('{http://sabredav.org/ns}root' => Element::Cdata.new('<foo&bar>'))
|
26
|
+
output = writer.output_memory
|
27
|
+
|
28
|
+
expected = <<XML
|
29
|
+
<?xml version="1.0"?>
|
30
|
+
<root xmlns="http://sabredav.org/ns"><![CDATA[<foo&bar>]]></root>
|
31
|
+
XML
|
32
|
+
|
33
|
+
assert_equal(expected, output)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# The intention for this reader class, is to read past the end element. This
|
2
|
+
# should trigger a ParseException
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
module Element
|
6
|
+
class Eater
|
7
|
+
include Element
|
8
|
+
|
9
|
+
# The serialize method is called during xml writing.
|
10
|
+
#
|
11
|
+
# It should use the writer argument to encode this object into Xml.
|
12
|
+
#
|
13
|
+
# Important note: it is not needed to create the parent element. The
|
14
|
+
# parent element is already created, and we only have to worry about
|
15
|
+
# attributes, child elements and text (if any).
|
16
|
+
#
|
17
|
+
# Important note 2: If you are writing any new elements, you are also
|
18
|
+
# responsible for closing them.
|
19
|
+
#
|
20
|
+
# @param [Writer] writer
|
21
|
+
# @return [void]
|
22
|
+
def xml_serialize(writer)
|
23
|
+
writer.start_element('{http://sabredav.org/ns}elem1')
|
24
|
+
writer.write_string('hiiii!')
|
25
|
+
writer.end_element
|
26
|
+
end
|
27
|
+
|
28
|
+
# The deserialize method is called during xml parsing.
|
29
|
+
#
|
30
|
+
# This method is called statictly, this is because in theory this method
|
31
|
+
# may be used as a type of constructor, or factory method.
|
32
|
+
#
|
33
|
+
# Often you want to return an instance of the current class, but you are
|
34
|
+
# free to return other data as well.
|
35
|
+
#
|
36
|
+
# Important note 2: You are responsible for advancing the reader to the
|
37
|
+
# next element. Not doing anything will result in a never-ending loop.
|
38
|
+
#
|
39
|
+
# If you just want to skip parsing for this element altogether, you can
|
40
|
+
# just call reader->next();
|
41
|
+
#
|
42
|
+
# reader->parseSubTree() will parse the entire sub-tree, and advance to
|
43
|
+
# the next element.
|
44
|
+
#
|
45
|
+
# @param [Reader] reader
|
46
|
+
# @return mixed
|
47
|
+
def self.xml_deserialize(reader)
|
48
|
+
reader.next
|
49
|
+
|
50
|
+
count = 1
|
51
|
+
while count > 0
|
52
|
+
reader.read
|
53
|
+
count -= 1 if reader.node_type == ::LibXML::XML::Reader::TYPE_END_ELEMENT
|
54
|
+
end
|
55
|
+
reader.read
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
class ElementsTest < Minitest::Test
|
6
|
+
def test_deserialize
|
7
|
+
input = <<BLA
|
8
|
+
<?xml version="1.0"?>
|
9
|
+
<root xmlns="http://sabredav.org/ns">
|
10
|
+
<listThingy>
|
11
|
+
<elem1 />
|
12
|
+
<elem2 />
|
13
|
+
<elem3 />
|
14
|
+
<elem4 attr="val" />
|
15
|
+
<elem5>content</elem5>
|
16
|
+
<elem6><subnode /></elem6>
|
17
|
+
</listThingy>
|
18
|
+
<listThingy />
|
19
|
+
<otherThing>
|
20
|
+
<elem1 />
|
21
|
+
<elem2 />
|
22
|
+
<elem3 />
|
23
|
+
</otherThing>
|
24
|
+
</root>
|
25
|
+
BLA
|
26
|
+
reader = Reader.new
|
27
|
+
reader.element_map = { '{http://sabredav.org/ns}listThingy' => Element::Elements }
|
28
|
+
reader.xml(input)
|
29
|
+
|
30
|
+
output = reader.parse
|
31
|
+
|
32
|
+
expected = {
|
33
|
+
'name' => '{http://sabredav.org/ns}root',
|
34
|
+
'value' => [
|
35
|
+
{
|
36
|
+
'name' => '{http://sabredav.org/ns}listThingy',
|
37
|
+
'value' => [
|
38
|
+
'{http://sabredav.org/ns}elem1',
|
39
|
+
'{http://sabredav.org/ns}elem2',
|
40
|
+
'{http://sabredav.org/ns}elem3',
|
41
|
+
'{http://sabredav.org/ns}elem4',
|
42
|
+
'{http://sabredav.org/ns}elem5',
|
43
|
+
'{http://sabredav.org/ns}elem6'
|
44
|
+
],
|
45
|
+
'attributes' => {}
|
46
|
+
},
|
47
|
+
{
|
48
|
+
'name' => '{http://sabredav.org/ns}listThingy',
|
49
|
+
'value' => [],
|
50
|
+
'attributes' => {}
|
51
|
+
},
|
52
|
+
{
|
53
|
+
'name' => '{http://sabredav.org/ns}otherThing',
|
54
|
+
'value' => [
|
55
|
+
{
|
56
|
+
'name' => '{http://sabredav.org/ns}elem1',
|
57
|
+
'value' => nil,
|
58
|
+
'attributes' => {}
|
59
|
+
},
|
60
|
+
{
|
61
|
+
'name' => '{http://sabredav.org/ns}elem2',
|
62
|
+
'value' => nil,
|
63
|
+
'attributes' => {}
|
64
|
+
},
|
65
|
+
{
|
66
|
+
'name' => '{http://sabredav.org/ns}elem3',
|
67
|
+
'value' => nil,
|
68
|
+
'attributes' => {}
|
69
|
+
}
|
70
|
+
],
|
71
|
+
'attributes' => {}
|
72
|
+
}
|
73
|
+
],
|
74
|
+
'attributes' => {}
|
75
|
+
}
|
76
|
+
|
77
|
+
assert_equal(expected, output)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_serialize
|
81
|
+
value = [
|
82
|
+
'{http://sabredav.org/ns}elem1',
|
83
|
+
'{http://sabredav.org/ns}elem2',
|
84
|
+
'{http://sabredav.org/ns}elem3',
|
85
|
+
'{http://sabredav.org/ns}elem4',
|
86
|
+
'{http://sabredav.org/ns}elem5',
|
87
|
+
'{http://sabredav.org/ns}elem6'
|
88
|
+
]
|
89
|
+
|
90
|
+
writer = Writer.new
|
91
|
+
writer.namespace_map = { 'http://sabredav.org/ns' => nil }
|
92
|
+
writer.open_memory
|
93
|
+
writer.start_document
|
94
|
+
writer.set_indent(true)
|
95
|
+
writer.write('{http://sabredav.org/ns}root' => Element::Elements.new(value))
|
96
|
+
output = writer.output_memory
|
97
|
+
|
98
|
+
expected = <<XML
|
99
|
+
<?xml version="1.0"?>
|
100
|
+
<root xmlns="http://sabredav.org/ns">
|
101
|
+
<elem1/>
|
102
|
+
<elem2/>
|
103
|
+
<elem3/>
|
104
|
+
<elem4/>
|
105
|
+
<elem5/>
|
106
|
+
<elem6/>
|
107
|
+
</root>
|
108
|
+
XML
|
109
|
+
assert_equal(expected, output)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
class KeyValueTest < Minitest::Test
|
6
|
+
def test_deserialize
|
7
|
+
input = <<BLA
|
8
|
+
<?xml version="1.0"?>
|
9
|
+
<root xmlns="http://sabredav.org/ns">
|
10
|
+
<struct>
|
11
|
+
<elem1 />
|
12
|
+
<elem2>hi</elem2>
|
13
|
+
<elem3>
|
14
|
+
<elem4>foo</elem4>
|
15
|
+
<elem5>foo & bar</elem5>
|
16
|
+
</elem3>
|
17
|
+
<elem6>Hi<!-- ignore me -->there</elem6>
|
18
|
+
</struct>
|
19
|
+
<struct />
|
20
|
+
<otherThing>
|
21
|
+
<elem1 />
|
22
|
+
</otherThing>
|
23
|
+
</root>
|
24
|
+
BLA
|
25
|
+
|
26
|
+
reader = Tilia::Xml::Reader.new
|
27
|
+
reader.element_map = { '{http://sabredav.org/ns}struct' => Tilia::Xml::Element::KeyValue }
|
28
|
+
reader.xml(input)
|
29
|
+
|
30
|
+
output = reader.parse
|
31
|
+
|
32
|
+
expected = {
|
33
|
+
'name' => '{http://sabredav.org/ns}root',
|
34
|
+
'value' => [
|
35
|
+
{
|
36
|
+
'name' => '{http://sabredav.org/ns}struct',
|
37
|
+
'value' => {
|
38
|
+
'{http://sabredav.org/ns}elem1' => nil,
|
39
|
+
'{http://sabredav.org/ns}elem2' => 'hi',
|
40
|
+
'{http://sabredav.org/ns}elem3' => [
|
41
|
+
{
|
42
|
+
'name' => '{http://sabredav.org/ns}elem4',
|
43
|
+
'value' => 'foo',
|
44
|
+
'attributes' => {}
|
45
|
+
},
|
46
|
+
{
|
47
|
+
'name' => '{http://sabredav.org/ns}elem5',
|
48
|
+
'value' => 'foo & bar',
|
49
|
+
'attributes' => {}
|
50
|
+
}
|
51
|
+
],
|
52
|
+
'{http://sabredav.org/ns}elem6' => 'Hithere'
|
53
|
+
},
|
54
|
+
'attributes' => {}
|
55
|
+
},
|
56
|
+
{
|
57
|
+
'name' => '{http://sabredav.org/ns}struct',
|
58
|
+
'value' => {},
|
59
|
+
'attributes' => {}
|
60
|
+
},
|
61
|
+
{
|
62
|
+
'name' => '{http://sabredav.org/ns}otherThing',
|
63
|
+
'value' => [
|
64
|
+
{
|
65
|
+
'name' => '{http://sabredav.org/ns}elem1',
|
66
|
+
'value' => nil,
|
67
|
+
'attributes' => {}
|
68
|
+
}
|
69
|
+
],
|
70
|
+
'attributes' => {}
|
71
|
+
}
|
72
|
+
],
|
73
|
+
'attributes' => {}
|
74
|
+
}
|
75
|
+
|
76
|
+
assert_equal(expected, output)
|
77
|
+
end
|
78
|
+
|
79
|
+
# This test was added to find out why an element gets eaten by the
|
80
|
+
# SabreDAV MKCOL parser.
|
81
|
+
def test_element_eater
|
82
|
+
input = <<BLA
|
83
|
+
<?xml version="1.0"?>
|
84
|
+
<mkcol xmlns="DAV:">
|
85
|
+
<set>
|
86
|
+
<prop>
|
87
|
+
<resourcetype><collection /></resourcetype>
|
88
|
+
<displayname>bla</displayname>
|
89
|
+
</prop>
|
90
|
+
</set>
|
91
|
+
</mkcol>
|
92
|
+
BLA
|
93
|
+
|
94
|
+
reader = Tilia::Xml::Reader.new
|
95
|
+
reader.element_map = {
|
96
|
+
'{DAV:}set' => Tilia::Xml::Element::KeyValue,
|
97
|
+
'{DAV:}prop' => Tilia::Xml::Element::KeyValue,
|
98
|
+
'{DAV:}resourcetype' => Tilia::Xml::Element::Elements
|
99
|
+
}
|
100
|
+
reader.xml(input)
|
101
|
+
|
102
|
+
expected = {
|
103
|
+
'name' => '{DAV:}mkcol',
|
104
|
+
'value' => [
|
105
|
+
{
|
106
|
+
'name' => '{DAV:}set',
|
107
|
+
'value' => {
|
108
|
+
'{DAV:}prop' => {
|
109
|
+
'{DAV:}resourcetype' => [
|
110
|
+
'{DAV:}collection'
|
111
|
+
],
|
112
|
+
'{DAV:}displayname' => 'bla'
|
113
|
+
}
|
114
|
+
},
|
115
|
+
'attributes' => {}
|
116
|
+
}
|
117
|
+
],
|
118
|
+
'attributes' => {}
|
119
|
+
}
|
120
|
+
|
121
|
+
assert_equal(expected, reader.parse)
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_serialize
|
125
|
+
value = {
|
126
|
+
'{http://sabredav.org/ns}elem1' => nil,
|
127
|
+
'{http://sabredav.org/ns}elem2' => 'textValue',
|
128
|
+
'{http://sabredav.org/ns}elem3' => {
|
129
|
+
'{http://sabredav.org/ns}elem4' => 'text2',
|
130
|
+
'{http://sabredav.org/ns}elem5' => nil
|
131
|
+
},
|
132
|
+
'{http://sabredav.org/ns}elem6' => 'text3'
|
133
|
+
}
|
134
|
+
|
135
|
+
writer = Tilia::Xml::Writer.new
|
136
|
+
writer.namespace_map = { 'http://sabredav.org/ns' => nil }
|
137
|
+
writer.open_memory
|
138
|
+
writer.start_document
|
139
|
+
writer.set_indent(true)
|
140
|
+
writer.write('{http://sabredav.org/ns}root' => Tilia::Xml::Element::KeyValue.new(value))
|
141
|
+
output = writer.output_memory
|
142
|
+
|
143
|
+
expected = <<XML
|
144
|
+
<?xml version="1.0"?>
|
145
|
+
<root xmlns="http://sabredav.org/ns">
|
146
|
+
<elem1/>
|
147
|
+
<elem2>textValue</elem2>
|
148
|
+
<elem3>
|
149
|
+
<elem4>text2</elem4>
|
150
|
+
<elem5/>
|
151
|
+
</elem3>
|
152
|
+
<elem6>text3</elem6>
|
153
|
+
</root>
|
154
|
+
XML
|
155
|
+
assert_equal(expected, output)
|
156
|
+
end
|
157
|
+
|
158
|
+
# I discovered that when there's no whitespace between elements, elements
|
159
|
+
# can get skipped.
|
160
|
+
def test_element_skip_problem
|
161
|
+
input = <<BLA
|
162
|
+
<?xml version="1.0" encoding="utf-8"?>
|
163
|
+
<root xmlns="http://sabredav.org/ns">
|
164
|
+
<elem3>val3</elem3><elem4>val4</elem4><elem5>val5</elem5></root>
|
165
|
+
BLA
|
166
|
+
|
167
|
+
reader = Tilia::Xml::Reader.new
|
168
|
+
reader.element_map = { '{http://sabredav.org/ns}root' => Tilia::Xml::Element::KeyValue }
|
169
|
+
reader.xml(input)
|
170
|
+
|
171
|
+
output = reader.parse
|
172
|
+
|
173
|
+
expected = {
|
174
|
+
'name' => '{http://sabredav.org/ns}root',
|
175
|
+
'value' => {
|
176
|
+
'{http://sabredav.org/ns}elem3' => 'val3',
|
177
|
+
'{http://sabredav.org/ns}elem4' => 'val4',
|
178
|
+
'{http://sabredav.org/ns}elem5' => 'val5'
|
179
|
+
},
|
180
|
+
'attributes' => {}
|
181
|
+
}
|
182
|
+
|
183
|
+
assert_equal(expected, output)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Tilia
|
2
|
+
module Xml
|
3
|
+
module Element
|
4
|
+
class Mock
|
5
|
+
include Element
|
6
|
+
|
7
|
+
# The serialize method is called during xml writing.
|
8
|
+
#
|
9
|
+
# It should use the writer argument to encode this object into XML.
|
10
|
+
#
|
11
|
+
# Important note: it is not needed to create the parent element. The
|
12
|
+
# parent element is already created, and we only have to worry about
|
13
|
+
# attributes, child elements and text (if any).
|
14
|
+
#
|
15
|
+
# Important note 2: If you are writing any new elements, you are also
|
16
|
+
# responsible for closing them.
|
17
|
+
#
|
18
|
+
# @param [Writer] writer
|
19
|
+
# @return [void]
|
20
|
+
def xml_serialize(writer)
|
21
|
+
writer.start_element('{http://sabredav.org/ns}elem1')
|
22
|
+
writer.write_string('hiiii!')
|
23
|
+
writer.end_element
|
24
|
+
end
|
25
|
+
|
26
|
+
# The deserialize method is called during xml parsing.
|
27
|
+
#
|
28
|
+
# This method is called statictly, this is because in theory this method
|
29
|
+
# may be used as a type of constructor, or factory method.
|
30
|
+
#
|
31
|
+
# Often you want to return an instance of the current class, but you are
|
32
|
+
# free to return other data as well.
|
33
|
+
#
|
34
|
+
# Important note 2: You are responsible for advancing the reader to the
|
35
|
+
# next element. Not doing anything will result in a never-ending loop.
|
36
|
+
#
|
37
|
+
# If you just want to skip parsing for this element altogether, you can
|
38
|
+
# just call reader->next();
|
39
|
+
#
|
40
|
+
# reader->parseSubTree() will parse the entire sub-tree, and advance to
|
41
|
+
# the next element.
|
42
|
+
#
|
43
|
+
# @param [Reader] reader
|
44
|
+
# @return mixed
|
45
|
+
def self.xml_deserialize(reader)
|
46
|
+
reader.next
|
47
|
+
'foobar'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Tilia
|
4
|
+
module Xml
|
5
|
+
class UriTest < Minitest::Test
|
6
|
+
def test_deserialize
|
7
|
+
input = <<BLA
|
8
|
+
<?xml version="1.0"?>
|
9
|
+
<root xmlns="http://sabredav.org/ns">
|
10
|
+
<uri>/foo/bar</uri>
|
11
|
+
</root>
|
12
|
+
BLA
|
13
|
+
reader = Tilia::Xml::Reader.new
|
14
|
+
reader.context_uri = 'http://example.org/'
|
15
|
+
reader.element_map = { '{http://sabredav.org/ns}uri' => Tilia::Xml::Element::Uri }
|
16
|
+
reader.xml(input)
|
17
|
+
output = reader.parse
|
18
|
+
|
19
|
+
expected = {
|
20
|
+
'name' => '{http://sabredav.org/ns}root',
|
21
|
+
'value' => [
|
22
|
+
{
|
23
|
+
'name' => '{http://sabredav.org/ns}uri',
|
24
|
+
'value' => Tilia::Xml::Element::Uri.new('http://example.org/foo/bar'),
|
25
|
+
'attributes' => {}
|
26
|
+
}
|
27
|
+
],
|
28
|
+
'attributes' => {}
|
29
|
+
}
|
30
|
+
|
31
|
+
assert_equal(expected, output)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_serialize
|
35
|
+
writer = Tilia::Xml::Writer.new
|
36
|
+
writer.namespace_map = { 'http://sabredav.org/ns' => nil }
|
37
|
+
writer.open_memory
|
38
|
+
writer.start_document
|
39
|
+
writer.set_indent(true)
|
40
|
+
writer.context_uri = 'http://example.org/'
|
41
|
+
writer.write('{http://sabredav.org/ns}root' => { '{http://sabredav.org/ns}uri' => Tilia::Xml::Element::Uri.new('/foo/bar') })
|
42
|
+
output = writer.output_memory
|
43
|
+
|
44
|
+
expected = <<XML
|
45
|
+
<?xml version="1.0"?>
|
46
|
+
<root xmlns="http://sabredav.org/ns">
|
47
|
+
<uri>http://example.org/foo/bar</uri>
|
48
|
+
</root>
|
49
|
+
XML
|
50
|
+
|
51
|
+
assert_equal(expected, output)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|