tilia-xml 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|