jordi-xml_struct 0.1.1 → 0.1.2
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/README.markdown +122 -3
- data/TODO +3 -0
- data/xml_struct.gemspec +2 -1
- metadata +2 -1
data/README.markdown
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
-
|
1
|
+
# XML Struct
|
2
2
|
|
3
|
-
|
3
|
+
(This is inspired by Python's `xml_objectify`)
|
4
|
+
|
5
|
+
XML Struct attempts to make accessing small, well-formed XML structures
|
6
|
+
convenient, by using dot notation (`foo.bar`) to represent both attributes
|
7
|
+
and child elements whenever possible, as well as by converting string values
|
8
|
+
onto native objects (`Fixnum`, `Float`, etc).
|
9
|
+
|
10
|
+
XML parsing libraries (in general) have interfaces that are useful when
|
11
|
+
one is using XML for its intended purpose, but cumbersome when one always
|
12
|
+
sends the same XML structure, and always process all of it in the same
|
13
|
+
way. This one is a bit different.
|
14
|
+
|
15
|
+
## Example usage
|
4
16
|
|
5
17
|
<recipe name="bread" prep_time="5 mins" cook_time="3 hours">
|
6
18
|
<title>Basic bread</title>
|
@@ -19,7 +31,8 @@ Documentation pending. For now:
|
|
19
31
|
</instructions>
|
20
32
|
</recipe>
|
21
33
|
|
22
|
-
|
34
|
+
require 'xml_struct'
|
35
|
+
recipe = XMLStruct.new io_with_recipe_xml_shown_above
|
23
36
|
|
24
37
|
recipe.name => "bread"
|
25
38
|
recipe.title == "Basic bread" => true
|
@@ -32,3 +45,109 @@ Documentation pending. For now:
|
|
32
45
|
recipe.instructions.first.upcase => "MIX ALL INGREDIENTS TOGETHER."
|
33
46
|
recipe.instructions.steps.size => 7
|
34
47
|
|
48
|
+
## Installation instructions
|
49
|
+
|
50
|
+
sudo gem install jordi-xml_struct --source http://gems.github.com
|
51
|
+
|
52
|
+
## Motivation
|
53
|
+
|
54
|
+
XML is an **extensible** markup language. It is extensible because it is
|
55
|
+
meant to define markup languages for **any** type of document, so new tags
|
56
|
+
are needed depending on the problem domain.
|
57
|
+
|
58
|
+
Sometimes, however, XML ends up being used to solve a much simpler problem:
|
59
|
+
the issue of passing a data-structure over the network, and/or between two
|
60
|
+
different languages. Tools like JSON or YAML are a much better fit for
|
61
|
+
this kind of job, but one doesn't always have that luxury.
|
62
|
+
|
63
|
+
## Caveats
|
64
|
+
|
65
|
+
The dot notation is used as follows. For the given file:
|
66
|
+
|
67
|
+
<outer id="root" name="foo">
|
68
|
+
<name>Outer Element</name>
|
69
|
+
</outer>
|
70
|
+
|
71
|
+
`outer.name` is the `<name>` element. Child elements are always looked up
|
72
|
+
first, then attributes. To access the attribute in the case of ambiguity,
|
73
|
+
use `outer[:attr => 'name']`.
|
74
|
+
|
75
|
+
`outer.id` is really `Object#id`, because all of the object methods are
|
76
|
+
preserved (this is on purpose). To access the attribute `id`, use
|
77
|
+
`outer[:attr => 'id']`, or `outer['id']` since there's no element/attribute
|
78
|
+
ambiguity.
|
79
|
+
|
80
|
+
## Features & Problems
|
81
|
+
|
82
|
+
### Collection auto-folding
|
83
|
+
|
84
|
+
Similar to XML::Simple, XML Struct folds same named elements at the same
|
85
|
+
level. For example:
|
86
|
+
|
87
|
+
<student>
|
88
|
+
<name>Bob</name>
|
89
|
+
<course>Math</course>
|
90
|
+
<course>Biology</course>
|
91
|
+
</student>
|
92
|
+
|
93
|
+
student = XMLStruct.new(xml_file)
|
94
|
+
|
95
|
+
student.course.is_a? Array => true
|
96
|
+
student.course.first == 'Math' => true
|
97
|
+
student.course.last == 'Biology => true
|
98
|
+
|
99
|
+
### Collection pluralization:
|
100
|
+
|
101
|
+
With the same file from the `Collection auto-folding` section above, you
|
102
|
+
also get this (courtesy of `ActiveSupport`'s `Inflector`):
|
103
|
+
|
104
|
+
student.courses == student.course => true
|
105
|
+
|
106
|
+
### Collection proxy:
|
107
|
+
|
108
|
+
Sometimes, collections are expressed with a container element in XML:
|
109
|
+
|
110
|
+
<student>
|
111
|
+
<name>Bob</name>
|
112
|
+
<courses>
|
113
|
+
<course>Math</course>
|
114
|
+
<course>Biology</course>
|
115
|
+
</courses>
|
116
|
+
</student>
|
117
|
+
|
118
|
+
In this case, since the container element `courses` has no text element
|
119
|
+
of its own, and it only has elements of one name under it, it delegates
|
120
|
+
all methods it doesn't contain to the collection below, so you get:
|
121
|
+
|
122
|
+
student.courses.collect { |c| c.downcase.to_sym } => [:math, :biology]
|
123
|
+
|
124
|
+
### Auto "type-casting"
|
125
|
+
|
126
|
+
Strings that look like integers are promoted via `to_i`, and similarly
|
127
|
+
floats via `to_f`. Strings that look like booleans are also promoted, but
|
128
|
+
only if called by their question mark names (such as `enabled?`.)
|
129
|
+
|
130
|
+
### Slow
|
131
|
+
|
132
|
+
So far, XML Struct uses REXML to do the actual XML parsing. Support
|
133
|
+
for using faster parsers is planned, leaving REXML as a fallback option.
|
134
|
+
|
135
|
+
### Recursive
|
136
|
+
|
137
|
+
The entire XML file is parsed using REXML right now, and then converted to
|
138
|
+
an XMLStruct of XMLStruct objects recursively. Deep files are bound to
|
139
|
+
throw `SystemStackError`, but for the kinds of files I need to read, things
|
140
|
+
are working fine so far. In any case, stream parsing is on the TODO list.
|
141
|
+
|
142
|
+
### Incomplete
|
143
|
+
|
144
|
+
It most likely doesn't work with a ton of features of complex XML files. I
|
145
|
+
will always try to accomodate those, as long as they don't make the basic
|
146
|
+
usage more complex. As usual, patches welcome.
|
147
|
+
|
148
|
+
## Legal
|
149
|
+
|
150
|
+
Copyright (c) 2008 Jordi Bunster, released under the MIT license
|
151
|
+
|
152
|
+
|
153
|
+
|
data/TODO
ADDED
data/xml_struct.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'xml_struct'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.2'
|
4
4
|
s.date = '2008-10-09'
|
5
5
|
|
6
6
|
s.author = 'Jordi Bunster'
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
README.markdown
|
28
28
|
Rakefile
|
29
29
|
WHATSNEW
|
30
|
+
TODO
|
30
31
|
lib
|
31
32
|
lib/jordi-xml_struct.rb
|
32
33
|
lib/xml_struct.rb
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jordi-xml_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordi Bunster
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- README.markdown
|
35
35
|
- Rakefile
|
36
36
|
- WHATSNEW
|
37
|
+
- TODO
|
37
38
|
- lib
|
38
39
|
- lib/jordi-xml_struct.rb
|
39
40
|
- lib/xml_struct.rb
|