clifton_lib 0.0.1 → 0.0.5
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/Gemfile.lock +1 -1
- data/README.md +8 -0
- data/lib/clifton_lib/version.rb +1 -1
- data/lib/clifton_lib/xml/xml_attribute.rb +3 -0
- data/lib/clifton_lib/xml/xml_document.rb +42 -10
- data/lib/clifton_lib/xml/xml_element.rb +1 -0
- data/lib/clifton_lib/xml/xml_node.rb +4 -0
- data/lib/clifton_lib/xml/xml_text_writer.rb +2 -0
- data/test/xml_document_tests.rb +66 -1
- metadata +6 -6
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -32,6 +32,14 @@ This implementation:
|
|
32
32
|
2. Inherently supports dynamic XML generation
|
33
33
|
3. Isn't DSL-ish.
|
34
34
|
|
35
|
+
## Revisions
|
36
|
+
|
37
|
+
0.0.5 - Added support to disallow a closing tag for HTML5 compatibility. For example, <img> is valid, <img></img> is seen as a stray ending tag.
|
38
|
+
0.0.4 - Added support to disallow self-closing tags for HTML5 compatibility. For example, <div>...</div> is valid, </div> is not.
|
39
|
+
0.0.3 - Added support for valueless attributes. Example: <nav class="top-bar" data-topbar/>
|
40
|
+
0.0.2 - Additional internal properties for associating the XmlDocument to elements and XmlElement to attributes.
|
41
|
+
0.0.1 - Initial version.
|
42
|
+
|
35
43
|
## A note about the code
|
36
44
|
|
37
45
|
You'll find that I do certain things, like explicitly return nil when the function isn't intended to return anything. This avoids accidental usage of a return from a function where
|
data/lib/clifton_lib/version.rb
CHANGED
@@ -4,11 +4,14 @@ module CliftonXml
|
|
4
4
|
class XmlAttribute
|
5
5
|
attr_accessor :name
|
6
6
|
attr_accessor :value
|
7
|
+
attr_accessor :xml_document
|
8
|
+
attr_accessor :xml_element
|
7
9
|
|
8
10
|
# XmlAttribute.new() {@name = [name]; @value = [value]}
|
9
11
|
def initialize(&block)
|
10
12
|
# this can use the form {@<attr> = <value>}
|
11
13
|
# allow for default constructor.
|
14
|
+
@xml_document = nil
|
12
15
|
instance_eval(&block) unless block.nil?
|
13
16
|
# yield self if block_given?
|
14
17
|
# this requires the form {|inst| inst.<attr> = <value>}
|
@@ -13,29 +13,45 @@ module CliftonXml
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# XmlDeclarationNode create_xml_declaration(string version, string encoding)
|
16
|
+
# Returns a node that will appear at the beginning of the document as:
|
17
|
+
# <?xml version="[ver]" encoding="[enc]" ?>
|
18
|
+
# The node must still be added to the parent (root) node with XmlNode#append_child.
|
16
19
|
def create_xml_declaration(version, encoding)
|
17
20
|
declNode = XmlDeclarationNode.new() {
|
18
21
|
@attributes << XmlAttribute.new() {@name='version'; @value=version}
|
19
22
|
@attributes << XmlAttribute.new() {@name='encoding'; @value=encoding}
|
20
23
|
}
|
21
24
|
|
22
|
-
declNode
|
23
|
-
end
|
25
|
+
declNode.xml_document = self
|
24
26
|
|
25
|
-
|
26
|
-
def create_attribute(name)
|
27
|
-
attr = XmlAttribute.new() {@name = name}
|
28
|
-
|
29
|
-
attr
|
27
|
+
declNode
|
30
28
|
end
|
31
29
|
|
32
30
|
# XmlElement create_element(string name)
|
31
|
+
# Return an XmlElement. Append to the desired node with XmlNode#append_child.
|
33
32
|
def create_element(name)
|
34
|
-
elem = XmlElement.new() {
|
33
|
+
elem = XmlElement.new() {
|
34
|
+
@name = name
|
35
|
+
}
|
36
|
+
|
37
|
+
elem.xml_document = self
|
35
38
|
|
36
39
|
elem
|
37
40
|
end
|
38
41
|
|
42
|
+
# XmlAttribute create_attribute(string name, string val = '')
|
43
|
+
# Returns an XmlAttribute. Append to the desired element with XmlElement#append_attribute.
|
44
|
+
def create_attribute(name, value = '')
|
45
|
+
attr = XmlAttribute.new() {
|
46
|
+
@name = name
|
47
|
+
@value = value
|
48
|
+
}
|
49
|
+
|
50
|
+
attr.xml_document = self
|
51
|
+
|
52
|
+
attr
|
53
|
+
end
|
54
|
+
|
39
55
|
def document_element()
|
40
56
|
# TODO
|
41
57
|
end
|
@@ -45,6 +61,7 @@ module CliftonXml
|
|
45
61
|
end
|
46
62
|
|
47
63
|
# void save(XmlTextWriter writer)
|
64
|
+
# Writes the XML tree to the string buffer in XmlTextWriter.
|
48
65
|
def save(writer)
|
49
66
|
write_nodes(writer, @child_nodes)
|
50
67
|
|
@@ -87,8 +104,17 @@ module CliftonXml
|
|
87
104
|
writer.write('</' + node.name + '>')
|
88
105
|
crlf_if_more_nodes(writer, nodes, idx)
|
89
106
|
else
|
90
|
-
# if no children and no inner text, use the abbreviated closing tag token.
|
91
|
-
|
107
|
+
# if no children and no inner text, use the abbreviated closing tag token unless no closing tag is required and unless self closing tags are not allowed.
|
108
|
+
if node.html_closing_tag
|
109
|
+
if writer.allow_self_closing_tags
|
110
|
+
writer.write('/>')
|
111
|
+
else
|
112
|
+
writer.write('></' + node.name + '>')
|
113
|
+
end
|
114
|
+
else
|
115
|
+
writer.write('>')
|
116
|
+
end
|
117
|
+
|
92
118
|
crlf_if_more_nodes(writer, nodes, idx)
|
93
119
|
end
|
94
120
|
end
|
@@ -106,7 +132,13 @@ module CliftonXml
|
|
106
132
|
attrs = []
|
107
133
|
|
108
134
|
node.attributes.each do |attr|
|
135
|
+
# special case:
|
136
|
+
# example: <nav class="top-bar" data-topbar>
|
137
|
+
if attr.value.nil?
|
138
|
+
attrs << attr.name
|
139
|
+
else
|
109
140
|
attrs << attr.name + '="' + attr.value + '"'
|
141
|
+
end
|
110
142
|
end
|
111
143
|
|
112
144
|
# separate them with a space
|
@@ -5,6 +5,8 @@ module CliftonXml
|
|
5
5
|
attr_accessor :name
|
6
6
|
attr_accessor :inner_text
|
7
7
|
attr_accessor :parent_node # Annoying rubyism -- if in the class itself, property must be read/writeable.
|
8
|
+
attr_accessor :xml_document
|
9
|
+
attr_accessor :html_closing_tag # Certain HTML closing tags are seen as "stray" if the exist, so we don't emit them if this is set to false.
|
8
10
|
attr_reader :attributes
|
9
11
|
attr_reader :child_nodes
|
10
12
|
|
@@ -15,6 +17,8 @@ module CliftonXml
|
|
15
17
|
@parent_node = nil
|
16
18
|
@name = nil
|
17
19
|
@inner_text = nil
|
20
|
+
@xml_document = nil
|
21
|
+
@html_closing_tag = true
|
18
22
|
|
19
23
|
self
|
20
24
|
end
|
@@ -5,6 +5,7 @@ module CliftonXml
|
|
5
5
|
# TODO: Implement streams, passing in an output stream to the constructor, like a StringWriter or FileWriter stream.
|
6
6
|
class XmlTextWriter
|
7
7
|
attr_accessor :formatting
|
8
|
+
attr_accessor :allow_self_closing_tags
|
8
9
|
attr_reader :output
|
9
10
|
|
10
11
|
# XmlTextWriter.new()
|
@@ -12,6 +13,7 @@ module CliftonXml
|
|
12
13
|
@output = ''
|
13
14
|
@indent = 0
|
14
15
|
@formatting = :none
|
16
|
+
@allow_self_closing_tags = true # HTML5 compatibility, set to false.
|
15
17
|
end
|
16
18
|
|
17
19
|
# void write(string str)
|
data/test/xml_document_tests.rb
CHANGED
@@ -104,6 +104,71 @@ class XmlDocumentTests < Test::Unit::TestCase
|
|
104
104
|
xdoc.save(tw)
|
105
105
|
output = tw.output
|
106
106
|
assert_equal %Q|<?xml version="1.0" encoding="UTF-8"?>\r\n<Products>\r\n <Product ID="1" Name="Apples">foobar</Product>\r\n <Product ID="2" Name="Oranges"/>\r\n</Products>|, output
|
107
|
-
end
|
108
107
|
end
|
109
108
|
|
109
|
+
def test_properties
|
110
|
+
xdoc = XmlDocument.new()
|
111
|
+
decl_node = xdoc.create_xml_declaration('1.0', 'UTF-8')
|
112
|
+
|
113
|
+
# decl node is assigned the xml_document.
|
114
|
+
assert_equal xdoc, decl_node.xml_document
|
115
|
+
|
116
|
+
# element is assigned the xml_document.
|
117
|
+
elem = xdoc.create_element('Element')
|
118
|
+
assert_equal xdoc, elem.xml_document
|
119
|
+
|
120
|
+
# element is assigned the parent.
|
121
|
+
xdoc.append_child(elem)
|
122
|
+
assert_equal xdoc, elem.parent_node
|
123
|
+
|
124
|
+
# attribute is assigned the xml document.
|
125
|
+
attr = xdoc.create_attribute('Attribute')
|
126
|
+
assert_equal xdoc, attr.xml_document
|
127
|
+
|
128
|
+
# attribute is assigned the owning element.
|
129
|
+
elem.append_attribute(attr)
|
130
|
+
assert_equal elem, attr.xml_element
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_attribute_without_value
|
134
|
+
# special case:
|
135
|
+
# example: <nav class="top-bar" data-topbar>
|
136
|
+
xdoc = XmlDocument.new()
|
137
|
+
elem = xdoc.create_element('Element')
|
138
|
+
xdoc.append_child(elem)
|
139
|
+
attr = xdoc.create_attribute('Attribute', nil)
|
140
|
+
elem.append_attribute(attr)
|
141
|
+
tw = XmlTextWriter.new()
|
142
|
+
tw.formatting = :indented
|
143
|
+
xdoc.save(tw)
|
144
|
+
output = tw.output
|
145
|
+
assert_equal %Q|<Element Attribute/>|, output
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_no_self_closing_tags
|
149
|
+
xdoc = XmlDocument.new()
|
150
|
+
elem = xdoc.create_element('Element')
|
151
|
+
xdoc.append_child(elem)
|
152
|
+
tw = XmlTextWriter.new()
|
153
|
+
tw.allow_self_closing_tags = false
|
154
|
+
tw.formatting = :indented
|
155
|
+
xdoc.save(tw)
|
156
|
+
output = tw.output
|
157
|
+
assert_equal %Q|<Element></Element>|, output
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_no_closing_tag
|
162
|
+
xdoc = XmlDocument.new()
|
163
|
+
elem = xdoc.create_element('img')
|
164
|
+
elem.html_closing_tag = false
|
165
|
+
xdoc.append_child(elem)
|
166
|
+
tw = XmlTextWriter.new()
|
167
|
+
tw.allow_self_closing_tags = false
|
168
|
+
tw.formatting = :indented
|
169
|
+
xdoc.save(tw)
|
170
|
+
output = tw.output
|
171
|
+
assert_equal %Q|<img>|, output
|
172
|
+
|
173
|
+
end
|
174
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clifton_lib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-04-
|
12
|
+
date: 2014-04-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
16
|
-
requirement: &
|
16
|
+
requirement: &25447320 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '1.3'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *25447320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &25447068 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *25447068
|
36
36
|
description: A collection of useful helper classes, initially a set of classes to
|
37
37
|
support creation and serialization of XML.
|
38
38
|
email:
|