xommelier 0.0.2 → 0.1.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.
- data/MIT-LICENSE +20 -0
- data/README.md +4 -1
- data/lib/xommelier/atom/generator.rb +2 -0
- data/lib/xommelier/atom/link.rb +1 -1
- data/lib/xommelier/version.rb +1 -1
- data/spec/fixtures/atom.rng.xml +597 -0
- data/spec/fixtures/atom.xsd.xml +240 -0
- data/spec/functional/atom_feed_building_spec.rb +32 -0
- data/spec/functional/atom_feed_parsing_spec.rb +86 -0
- data/spec/lib/xommelier/xml/element/serialization_spec.rb +1 -11
- data/spec/support/fixtures.rb +3 -0
- data/xommelier.gemspec +1 -1
- metadata +23 -12
- data/spec/fixtures/{feed.atom → feed.atom.xml} +0 -0
- data/spec/fixtures/{simple_feed.atom → simple_feed.atom.xml} +1 -1
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
© Alexander Semyonov, 2011-2012
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -12,8 +12,11 @@ Xommelier is work in progress.
|
|
12
12
|
|
13
13
|
You can see example code in examples/ folder.
|
14
14
|
|
15
|
-
##
|
15
|
+
## TODO
|
16
16
|
|
17
|
+
* Validating built XML against RelaxNG and XML Schema
|
17
18
|
* Implementation that support more than one namespace in XML class
|
18
19
|
* Converting XML Schema, RelaxNG, RelaxNG Compact and DTD into Xommelier Ruby DSL
|
19
20
|
* ActiveRecord-like automatic loading of XML Schema, RelaxNG, RelaxNG Compact and DTD without needing to write it down into ruby code
|
21
|
+
|
22
|
+
© Alexander Semyonov, 2011-2012. See MIT-LICENSE for details
|
data/lib/xommelier/atom/link.rb
CHANGED
data/lib/xommelier/version.rb
CHANGED
@@ -0,0 +1,597 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!--
|
3
|
+
-*- rnc -*-
|
4
|
+
RELAX NG Compact Syntax Grammar for the
|
5
|
+
Atom Format Specification Version 11
|
6
|
+
-->
|
7
|
+
<grammar xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:s="http://www.ascc.net/xml/schematron" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
8
|
+
<start>
|
9
|
+
<choice>
|
10
|
+
<ref name="atomFeed"/>
|
11
|
+
<ref name="atomEntry"/>
|
12
|
+
</choice>
|
13
|
+
</start>
|
14
|
+
<!-- Common attributes -->
|
15
|
+
<define name="atomCommonAttributes">
|
16
|
+
<optional>
|
17
|
+
<attribute name="xml:base">
|
18
|
+
<ref name="atomUri"/>
|
19
|
+
</attribute>
|
20
|
+
</optional>
|
21
|
+
<optional>
|
22
|
+
<attribute name="xml:lang">
|
23
|
+
<ref name="atomLanguageTag"/>
|
24
|
+
</attribute>
|
25
|
+
</optional>
|
26
|
+
<zeroOrMore>
|
27
|
+
<ref name="undefinedAttribute"/>
|
28
|
+
</zeroOrMore>
|
29
|
+
</define>
|
30
|
+
<!-- Text Constructs -->
|
31
|
+
<define name="atomPlainTextConstruct">
|
32
|
+
<ref name="atomCommonAttributes"/>
|
33
|
+
<optional>
|
34
|
+
<attribute name="type">
|
35
|
+
<choice>
|
36
|
+
<value>text</value>
|
37
|
+
<value>html</value>
|
38
|
+
</choice>
|
39
|
+
</attribute>
|
40
|
+
</optional>
|
41
|
+
<text/>
|
42
|
+
</define>
|
43
|
+
<define name="atomXHTMLTextConstruct">
|
44
|
+
<ref name="atomCommonAttributes"/>
|
45
|
+
<attribute name="type">
|
46
|
+
<value>xhtml</value>
|
47
|
+
</attribute>
|
48
|
+
<ref name="xhtmlDiv"/>
|
49
|
+
</define>
|
50
|
+
<define name="atomTextConstruct">
|
51
|
+
<choice>
|
52
|
+
<ref name="atomPlainTextConstruct"/>
|
53
|
+
<ref name="atomXHTMLTextConstruct"/>
|
54
|
+
</choice>
|
55
|
+
</define>
|
56
|
+
<!-- Person Construct -->
|
57
|
+
<define name="atomPersonConstruct">
|
58
|
+
<ref name="atomCommonAttributes"/>
|
59
|
+
<interleave>
|
60
|
+
<element name="atom:name">
|
61
|
+
<text/>
|
62
|
+
</element>
|
63
|
+
<optional>
|
64
|
+
<element name="atom:uri">
|
65
|
+
<ref name="atomUri"/>
|
66
|
+
</element>
|
67
|
+
</optional>
|
68
|
+
<optional>
|
69
|
+
<element name="atom:email">
|
70
|
+
<ref name="atomEmailAddress"/>
|
71
|
+
</element>
|
72
|
+
</optional>
|
73
|
+
<zeroOrMore>
|
74
|
+
<ref name="extensionElement"/>
|
75
|
+
</zeroOrMore>
|
76
|
+
</interleave>
|
77
|
+
</define>
|
78
|
+
<!-- Date Construct -->
|
79
|
+
<define name="atomDateConstruct">
|
80
|
+
<ref name="atomCommonAttributes"/>
|
81
|
+
<data type="dateTime"/>
|
82
|
+
</define>
|
83
|
+
<!-- atom:feed -->
|
84
|
+
<define name="atomFeed">
|
85
|
+
<element name="atom:feed">
|
86
|
+
<s:rule context="atom:feed">
|
87
|
+
<s:assert test="atom:author or not(atom:entry[not(atom:author)])">An atom:feed must have an atom:author unless all of its atom:entry children have an atom:author.</s:assert>
|
88
|
+
</s:rule>
|
89
|
+
<ref name="atomCommonAttributes"/>
|
90
|
+
<interleave>
|
91
|
+
<zeroOrMore>
|
92
|
+
<ref name="atomAuthor"/>
|
93
|
+
</zeroOrMore>
|
94
|
+
<zeroOrMore>
|
95
|
+
<ref name="atomCategory"/>
|
96
|
+
</zeroOrMore>
|
97
|
+
<zeroOrMore>
|
98
|
+
<ref name="atomContributor"/>
|
99
|
+
</zeroOrMore>
|
100
|
+
<optional>
|
101
|
+
<ref name="atomGenerator"/>
|
102
|
+
</optional>
|
103
|
+
<optional>
|
104
|
+
<ref name="atomIcon"/>
|
105
|
+
</optional>
|
106
|
+
<ref name="atomId"/>
|
107
|
+
<zeroOrMore>
|
108
|
+
<ref name="atomLink"/>
|
109
|
+
</zeroOrMore>
|
110
|
+
<optional>
|
111
|
+
<ref name="atomLogo"/>
|
112
|
+
</optional>
|
113
|
+
<optional>
|
114
|
+
<ref name="atomRights"/>
|
115
|
+
</optional>
|
116
|
+
<optional>
|
117
|
+
<ref name="atomSubtitle"/>
|
118
|
+
</optional>
|
119
|
+
<ref name="atomTitle"/>
|
120
|
+
<ref name="atomUpdated"/>
|
121
|
+
<zeroOrMore>
|
122
|
+
<ref name="extensionElement"/>
|
123
|
+
</zeroOrMore>
|
124
|
+
</interleave>
|
125
|
+
<zeroOrMore>
|
126
|
+
<ref name="atomEntry"/>
|
127
|
+
</zeroOrMore>
|
128
|
+
</element>
|
129
|
+
</define>
|
130
|
+
<!-- atom:entry -->
|
131
|
+
<define name="atomEntry">
|
132
|
+
<element name="atom:entry">
|
133
|
+
<s:rule context="atom:entry">
|
134
|
+
<s:assert test="atom:link[@rel='alternate'] or atom:link[not(@rel)] or atom:content">An atom:entry must have at least one atom:link element with a rel attribute of 'alternate' or an atom:content.</s:assert>
|
135
|
+
</s:rule>
|
136
|
+
<s:rule context="atom:entry">
|
137
|
+
<s:assert test="atom:author or ../atom:author or atom:source/atom:author">An atom:entry must have an atom:author if its feed does not.</s:assert>
|
138
|
+
</s:rule>
|
139
|
+
<ref name="atomCommonAttributes"/>
|
140
|
+
<interleave>
|
141
|
+
<zeroOrMore>
|
142
|
+
<ref name="atomAuthor"/>
|
143
|
+
</zeroOrMore>
|
144
|
+
<zeroOrMore>
|
145
|
+
<ref name="atomCategory"/>
|
146
|
+
</zeroOrMore>
|
147
|
+
<optional>
|
148
|
+
<ref name="atomContent"/>
|
149
|
+
</optional>
|
150
|
+
<zeroOrMore>
|
151
|
+
<ref name="atomContributor"/>
|
152
|
+
</zeroOrMore>
|
153
|
+
<ref name="atomId"/>
|
154
|
+
<zeroOrMore>
|
155
|
+
<ref name="atomLink"/>
|
156
|
+
</zeroOrMore>
|
157
|
+
<optional>
|
158
|
+
<ref name="atomPublished"/>
|
159
|
+
</optional>
|
160
|
+
<optional>
|
161
|
+
<ref name="atomRights"/>
|
162
|
+
</optional>
|
163
|
+
<optional>
|
164
|
+
<ref name="atomSource"/>
|
165
|
+
</optional>
|
166
|
+
<optional>
|
167
|
+
<ref name="atomSummary"/>
|
168
|
+
</optional>
|
169
|
+
<ref name="atomTitle"/>
|
170
|
+
<ref name="atomUpdated"/>
|
171
|
+
<zeroOrMore>
|
172
|
+
<ref name="extensionElement"/>
|
173
|
+
</zeroOrMore>
|
174
|
+
</interleave>
|
175
|
+
</element>
|
176
|
+
</define>
|
177
|
+
<!-- atom:content -->
|
178
|
+
<define name="atomInlineTextContent">
|
179
|
+
<element name="atom:content">
|
180
|
+
<ref name="atomCommonAttributes"/>
|
181
|
+
<optional>
|
182
|
+
<attribute name="type">
|
183
|
+
<choice>
|
184
|
+
<value>text</value>
|
185
|
+
<value>html</value>
|
186
|
+
</choice>
|
187
|
+
</attribute>
|
188
|
+
</optional>
|
189
|
+
<zeroOrMore>
|
190
|
+
<text/>
|
191
|
+
</zeroOrMore>
|
192
|
+
</element>
|
193
|
+
</define>
|
194
|
+
<define name="atomInlineXHTMLContent">
|
195
|
+
<element name="atom:content">
|
196
|
+
<ref name="atomCommonAttributes"/>
|
197
|
+
<attribute name="type">
|
198
|
+
<value>xhtml</value>
|
199
|
+
</attribute>
|
200
|
+
<ref name="xhtmlDiv"/>
|
201
|
+
</element>
|
202
|
+
</define>
|
203
|
+
<define name="atomInlineOtherContent">
|
204
|
+
<element name="atom:content">
|
205
|
+
<ref name="atomCommonAttributes"/>
|
206
|
+
<optional>
|
207
|
+
<attribute name="type">
|
208
|
+
<ref name="atomMediaType"/>
|
209
|
+
</attribute>
|
210
|
+
</optional>
|
211
|
+
<zeroOrMore>
|
212
|
+
<choice>
|
213
|
+
<text/>
|
214
|
+
<ref name="anyElement"/>
|
215
|
+
</choice>
|
216
|
+
</zeroOrMore>
|
217
|
+
</element>
|
218
|
+
</define>
|
219
|
+
<define name="atomOutOfLineContent">
|
220
|
+
<element name="atom:content">
|
221
|
+
<ref name="atomCommonAttributes"/>
|
222
|
+
<optional>
|
223
|
+
<attribute name="type">
|
224
|
+
<ref name="atomMediaType"/>
|
225
|
+
</attribute>
|
226
|
+
</optional>
|
227
|
+
<attribute name="src">
|
228
|
+
<ref name="atomUri"/>
|
229
|
+
</attribute>
|
230
|
+
<empty/>
|
231
|
+
</element>
|
232
|
+
</define>
|
233
|
+
<define name="atomContent">
|
234
|
+
<choice>
|
235
|
+
<ref name="atomInlineTextContent"/>
|
236
|
+
<ref name="atomInlineXHTMLContent"/>
|
237
|
+
<ref name="atomInlineOtherContent"/>
|
238
|
+
<ref name="atomOutOfLineContent"/>
|
239
|
+
</choice>
|
240
|
+
</define>
|
241
|
+
<!-- atom:author -->
|
242
|
+
<define name="atomAuthor">
|
243
|
+
<element name="atom:author">
|
244
|
+
<ref name="atomPersonConstruct"/>
|
245
|
+
</element>
|
246
|
+
</define>
|
247
|
+
<!-- atom:category -->
|
248
|
+
<define name="atomCategory">
|
249
|
+
<element name="atom:category">
|
250
|
+
<ref name="atomCommonAttributes"/>
|
251
|
+
<attribute name="term"/>
|
252
|
+
<optional>
|
253
|
+
<attribute name="scheme">
|
254
|
+
<ref name="atomUri"/>
|
255
|
+
</attribute>
|
256
|
+
</optional>
|
257
|
+
<optional>
|
258
|
+
<attribute name="label"/>
|
259
|
+
</optional>
|
260
|
+
<ref name="undefinedContent"/>
|
261
|
+
</element>
|
262
|
+
</define>
|
263
|
+
<!-- atom:contributor -->
|
264
|
+
<define name="atomContributor">
|
265
|
+
<element name="atom:contributor">
|
266
|
+
<ref name="atomPersonConstruct"/>
|
267
|
+
</element>
|
268
|
+
</define>
|
269
|
+
<!-- atom:generator -->
|
270
|
+
<define name="atomGenerator">
|
271
|
+
<element name="atom:generator">
|
272
|
+
<ref name="atomCommonAttributes"/>
|
273
|
+
<optional>
|
274
|
+
<attribute name="uri">
|
275
|
+
<ref name="atomUri"/>
|
276
|
+
</attribute>
|
277
|
+
</optional>
|
278
|
+
<optional>
|
279
|
+
<attribute name="version"/>
|
280
|
+
</optional>
|
281
|
+
<text/>
|
282
|
+
</element>
|
283
|
+
</define>
|
284
|
+
<!-- atom:icon -->
|
285
|
+
<define name="atomIcon">
|
286
|
+
<element name="atom:icon">
|
287
|
+
<ref name="atomCommonAttributes"/>
|
288
|
+
<ref name="atomUri"/>
|
289
|
+
</element>
|
290
|
+
</define>
|
291
|
+
<!-- atom:id -->
|
292
|
+
<define name="atomId">
|
293
|
+
<element name="atom:id">
|
294
|
+
<ref name="atomCommonAttributes"/>
|
295
|
+
<ref name="atomUri"/>
|
296
|
+
</element>
|
297
|
+
</define>
|
298
|
+
<!-- atom:logo -->
|
299
|
+
<define name="atomLogo">
|
300
|
+
<element name="atom:logo">
|
301
|
+
<ref name="atomCommonAttributes"/>
|
302
|
+
<ref name="atomUri"/>
|
303
|
+
</element>
|
304
|
+
</define>
|
305
|
+
<!-- atom:link -->
|
306
|
+
<define name="atomLink">
|
307
|
+
<element name="atom:link">
|
308
|
+
<ref name="atomCommonAttributes"/>
|
309
|
+
<attribute name="href">
|
310
|
+
<ref name="atomUri"/>
|
311
|
+
</attribute>
|
312
|
+
<optional>
|
313
|
+
<attribute name="rel">
|
314
|
+
<choice>
|
315
|
+
<ref name="atomNCName"/>
|
316
|
+
<ref name="atomUri"/>
|
317
|
+
</choice>
|
318
|
+
</attribute>
|
319
|
+
</optional>
|
320
|
+
<optional>
|
321
|
+
<attribute name="type">
|
322
|
+
<ref name="atomMediaType"/>
|
323
|
+
</attribute>
|
324
|
+
</optional>
|
325
|
+
<optional>
|
326
|
+
<attribute name="hreflang">
|
327
|
+
<ref name="atomLanguageTag"/>
|
328
|
+
</attribute>
|
329
|
+
</optional>
|
330
|
+
<optional>
|
331
|
+
<attribute name="title"/>
|
332
|
+
</optional>
|
333
|
+
<optional>
|
334
|
+
<attribute name="length"/>
|
335
|
+
</optional>
|
336
|
+
<ref name="undefinedContent"/>
|
337
|
+
</element>
|
338
|
+
</define>
|
339
|
+
<!-- atom:published -->
|
340
|
+
<define name="atomPublished">
|
341
|
+
<element name="atom:published">
|
342
|
+
<ref name="atomDateConstruct"/>
|
343
|
+
</element>
|
344
|
+
</define>
|
345
|
+
<!-- atom:rights -->
|
346
|
+
<define name="atomRights">
|
347
|
+
<element name="atom:rights">
|
348
|
+
<ref name="atomTextConstruct"/>
|
349
|
+
</element>
|
350
|
+
</define>
|
351
|
+
<!-- atom:source -->
|
352
|
+
<define name="atomSource">
|
353
|
+
<element name="atom:source">
|
354
|
+
<ref name="atomCommonAttributes"/>
|
355
|
+
<interleave>
|
356
|
+
<zeroOrMore>
|
357
|
+
<ref name="atomAuthor"/>
|
358
|
+
</zeroOrMore>
|
359
|
+
<zeroOrMore>
|
360
|
+
<ref name="atomCategory"/>
|
361
|
+
</zeroOrMore>
|
362
|
+
<zeroOrMore>
|
363
|
+
<ref name="atomContributor"/>
|
364
|
+
</zeroOrMore>
|
365
|
+
<optional>
|
366
|
+
<ref name="atomGenerator"/>
|
367
|
+
</optional>
|
368
|
+
<optional>
|
369
|
+
<ref name="atomIcon"/>
|
370
|
+
</optional>
|
371
|
+
<optional>
|
372
|
+
<ref name="atomId"/>
|
373
|
+
</optional>
|
374
|
+
<zeroOrMore>
|
375
|
+
<ref name="atomLink"/>
|
376
|
+
</zeroOrMore>
|
377
|
+
<optional>
|
378
|
+
<ref name="atomLogo"/>
|
379
|
+
</optional>
|
380
|
+
<optional>
|
381
|
+
<ref name="atomRights"/>
|
382
|
+
</optional>
|
383
|
+
<optional>
|
384
|
+
<ref name="atomSubtitle"/>
|
385
|
+
</optional>
|
386
|
+
<optional>
|
387
|
+
<ref name="atomTitle"/>
|
388
|
+
</optional>
|
389
|
+
<optional>
|
390
|
+
<ref name="atomUpdated"/>
|
391
|
+
</optional>
|
392
|
+
<zeroOrMore>
|
393
|
+
<ref name="extensionElement"/>
|
394
|
+
</zeroOrMore>
|
395
|
+
</interleave>
|
396
|
+
</element>
|
397
|
+
</define>
|
398
|
+
<!-- atom:subtitle -->
|
399
|
+
<define name="atomSubtitle">
|
400
|
+
<element name="atom:subtitle">
|
401
|
+
<ref name="atomTextConstruct"/>
|
402
|
+
</element>
|
403
|
+
</define>
|
404
|
+
<!-- atom:summary -->
|
405
|
+
<define name="atomSummary">
|
406
|
+
<element name="atom:summary">
|
407
|
+
<ref name="atomTextConstruct"/>
|
408
|
+
</element>
|
409
|
+
</define>
|
410
|
+
<!-- atom:title -->
|
411
|
+
<define name="atomTitle">
|
412
|
+
<element name="atom:title">
|
413
|
+
<ref name="atomTextConstruct"/>
|
414
|
+
</element>
|
415
|
+
</define>
|
416
|
+
<!-- atom:updated -->
|
417
|
+
<define name="atomUpdated">
|
418
|
+
<element name="atom:updated">
|
419
|
+
<ref name="atomDateConstruct"/>
|
420
|
+
</element>
|
421
|
+
</define>
|
422
|
+
<!-- Low-level simple types -->
|
423
|
+
<define name="atomNCName">
|
424
|
+
<data type="string">
|
425
|
+
<param name="minLength">1</param>
|
426
|
+
<param name="pattern">[^:]*</param>
|
427
|
+
</data>
|
428
|
+
</define>
|
429
|
+
<!-- Whatever a media type is, it contains at least one slash -->
|
430
|
+
<define name="atomMediaType">
|
431
|
+
<data type="string">
|
432
|
+
<param name="pattern">.+/.+</param>
|
433
|
+
</data>
|
434
|
+
</define>
|
435
|
+
<!-- As defined in RFC 3066 -->
|
436
|
+
<define name="atomLanguageTag">
|
437
|
+
<data type="string">
|
438
|
+
<param name="pattern">[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*</param>
|
439
|
+
</data>
|
440
|
+
</define>
|
441
|
+
<!--
|
442
|
+
Unconstrained; it's not entirely clear how IRI fit into
|
443
|
+
xsd:anyURI so let's not try to constrain it here
|
444
|
+
-->
|
445
|
+
<define name="atomUri">
|
446
|
+
<text/>
|
447
|
+
</define>
|
448
|
+
<!-- Whatever an email address is, it contains at least one @ -->
|
449
|
+
<define name="atomEmailAddress">
|
450
|
+
<data type="string">
|
451
|
+
<param name="pattern">.+@.+</param>
|
452
|
+
</data>
|
453
|
+
</define>
|
454
|
+
<!-- Simple Extension -->
|
455
|
+
<define name="simpleExtensionElement">
|
456
|
+
<element>
|
457
|
+
<anyName>
|
458
|
+
<except>
|
459
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
460
|
+
</except>
|
461
|
+
</anyName>
|
462
|
+
<text/>
|
463
|
+
</element>
|
464
|
+
</define>
|
465
|
+
<!-- Structured Extension -->
|
466
|
+
<define name="structuredExtensionElement">
|
467
|
+
<element>
|
468
|
+
<anyName>
|
469
|
+
<except>
|
470
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
471
|
+
</except>
|
472
|
+
</anyName>
|
473
|
+
<choice>
|
474
|
+
<group>
|
475
|
+
<oneOrMore>
|
476
|
+
<attribute>
|
477
|
+
<anyName/>
|
478
|
+
</attribute>
|
479
|
+
</oneOrMore>
|
480
|
+
<zeroOrMore>
|
481
|
+
<choice>
|
482
|
+
<text/>
|
483
|
+
<ref name="anyElement"/>
|
484
|
+
</choice>
|
485
|
+
</zeroOrMore>
|
486
|
+
</group>
|
487
|
+
<group>
|
488
|
+
<zeroOrMore>
|
489
|
+
<attribute>
|
490
|
+
<anyName/>
|
491
|
+
</attribute>
|
492
|
+
</zeroOrMore>
|
493
|
+
<group>
|
494
|
+
<optional>
|
495
|
+
<text/>
|
496
|
+
</optional>
|
497
|
+
<oneOrMore>
|
498
|
+
<ref name="anyElement"/>
|
499
|
+
</oneOrMore>
|
500
|
+
<zeroOrMore>
|
501
|
+
<choice>
|
502
|
+
<text/>
|
503
|
+
<ref name="anyElement"/>
|
504
|
+
</choice>
|
505
|
+
</zeroOrMore>
|
506
|
+
</group>
|
507
|
+
</group>
|
508
|
+
</choice>
|
509
|
+
</element>
|
510
|
+
</define>
|
511
|
+
<!-- Other Extensibility -->
|
512
|
+
<define name="extensionElement">
|
513
|
+
<choice>
|
514
|
+
<ref name="simpleExtensionElement"/>
|
515
|
+
<ref name="structuredExtensionElement"/>
|
516
|
+
</choice>
|
517
|
+
</define>
|
518
|
+
<define name="undefinedAttribute">
|
519
|
+
<attribute>
|
520
|
+
<anyName>
|
521
|
+
<except>
|
522
|
+
<name>xml:base</name>
|
523
|
+
<name>xml:lang</name>
|
524
|
+
<nsName ns=""/>
|
525
|
+
</except>
|
526
|
+
</anyName>
|
527
|
+
</attribute>
|
528
|
+
</define>
|
529
|
+
<define name="undefinedContent">
|
530
|
+
<zeroOrMore>
|
531
|
+
<choice>
|
532
|
+
<text/>
|
533
|
+
<ref name="anyForeignElement"/>
|
534
|
+
</choice>
|
535
|
+
</zeroOrMore>
|
536
|
+
</define>
|
537
|
+
<define name="anyElement">
|
538
|
+
<element>
|
539
|
+
<anyName/>
|
540
|
+
<zeroOrMore>
|
541
|
+
<choice>
|
542
|
+
<attribute>
|
543
|
+
<anyName/>
|
544
|
+
</attribute>
|
545
|
+
<text/>
|
546
|
+
<ref name="anyElement"/>
|
547
|
+
</choice>
|
548
|
+
</zeroOrMore>
|
549
|
+
</element>
|
550
|
+
</define>
|
551
|
+
<define name="anyForeignElement">
|
552
|
+
<element>
|
553
|
+
<anyName>
|
554
|
+
<except>
|
555
|
+
<nsName ns="http://www.w3.org/2005/Atom"/>
|
556
|
+
</except>
|
557
|
+
</anyName>
|
558
|
+
<zeroOrMore>
|
559
|
+
<choice>
|
560
|
+
<attribute>
|
561
|
+
<anyName/>
|
562
|
+
</attribute>
|
563
|
+
<text/>
|
564
|
+
<ref name="anyElement"/>
|
565
|
+
</choice>
|
566
|
+
</zeroOrMore>
|
567
|
+
</element>
|
568
|
+
</define>
|
569
|
+
<!-- XHTML -->
|
570
|
+
<define name="anyXHTML">
|
571
|
+
<element>
|
572
|
+
<nsName ns="http://www.w3.org/1999/xhtml"/>
|
573
|
+
<zeroOrMore>
|
574
|
+
<choice>
|
575
|
+
<attribute>
|
576
|
+
<anyName/>
|
577
|
+
</attribute>
|
578
|
+
<text/>
|
579
|
+
<ref name="anyXHTML"/>
|
580
|
+
</choice>
|
581
|
+
</zeroOrMore>
|
582
|
+
</element>
|
583
|
+
</define>
|
584
|
+
<define name="xhtmlDiv">
|
585
|
+
<element name="xhtml:div">
|
586
|
+
<zeroOrMore>
|
587
|
+
<choice>
|
588
|
+
<attribute>
|
589
|
+
<anyName/>
|
590
|
+
</attribute>
|
591
|
+
<text/>
|
592
|
+
<ref name="anyXHTML"/>
|
593
|
+
</choice>
|
594
|
+
</zeroOrMore>
|
595
|
+
</element>
|
596
|
+
</define>
|
597
|
+
</grammar>
|
@@ -0,0 +1,240 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<xs:schema targetNamespace="http://www.w3.org/2005/Atom" elementFormDefault="qualified"
|
3
|
+
attributeFormDefault="unqualified"
|
4
|
+
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
5
|
+
<xs:annotation>
|
6
|
+
<xs:documentation>
|
7
|
+
This version of the Atom schema is based on version 1.0 of the format specifications,
|
8
|
+
found here http://www.atomenabled.org/developers/syndication/atom-format-spec.php.
|
9
|
+
</xs:documentation>
|
10
|
+
</xs:annotation>
|
11
|
+
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/03/xml.xsd" />
|
12
|
+
<xs:annotation>
|
13
|
+
<xs:documentation>
|
14
|
+
An Atom document may have two root elements, feed and entry, as defined in section 2.
|
15
|
+
</xs:documentation>
|
16
|
+
</xs:annotation>
|
17
|
+
<xs:element name="feed" type="atom:feedType"/>
|
18
|
+
<xs:element name="entry" type="atom:entryType"/>
|
19
|
+
<xs:complexType name="textType" mixed="true">
|
20
|
+
<xs:annotation>
|
21
|
+
<xs:documentation>
|
22
|
+
The Atom text construct is defined in section 3.1 of the format spec.
|
23
|
+
</xs:documentation>
|
24
|
+
</xs:annotation>
|
25
|
+
<xs:sequence>
|
26
|
+
<xs:any namespace="http://www.w3.org/1999/xhtml" minOccurs="0"/>
|
27
|
+
</xs:sequence>
|
28
|
+
<xs:attribute name="type" >
|
29
|
+
<xs:simpleType>
|
30
|
+
<xs:restriction base="xs:token">
|
31
|
+
<xs:enumeration value="text"/>
|
32
|
+
<xs:enumeration value="html"/>
|
33
|
+
<xs:enumeration value="xhtml"/>
|
34
|
+
</xs:restriction>
|
35
|
+
</xs:simpleType>
|
36
|
+
</xs:attribute>
|
37
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
38
|
+
</xs:complexType>
|
39
|
+
<xs:complexType name="personType">
|
40
|
+
<xs:annotation>
|
41
|
+
<xs:documentation>
|
42
|
+
The Atom person construct is defined in section 3.2 of the format spec.
|
43
|
+
</xs:documentation>
|
44
|
+
</xs:annotation>
|
45
|
+
<xs:choice minOccurs="1" maxOccurs="unbounded">
|
46
|
+
<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
|
47
|
+
<xs:element name="uri" type="atom:uriType" minOccurs="0" maxOccurs="1" />
|
48
|
+
<xs:element name="email" type="atom:emailType" minOccurs="0" maxOccurs="1" />
|
49
|
+
<xs:any namespace="##other"/>
|
50
|
+
</xs:choice>
|
51
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
52
|
+
</xs:complexType>
|
53
|
+
<xs:simpleType name="emailType">
|
54
|
+
<xs:annotation>
|
55
|
+
<xs:documentation>
|
56
|
+
Schema definition for an email address.
|
57
|
+
</xs:documentation>
|
58
|
+
</xs:annotation>
|
59
|
+
<xs:restriction base="xs:normalizedString">
|
60
|
+
<xs:pattern value="\w+@(\w+\.)+\w+" />
|
61
|
+
</xs:restriction>
|
62
|
+
</xs:simpleType>
|
63
|
+
<xs:complexType name="feedType">
|
64
|
+
<xs:annotation>
|
65
|
+
<xs:documentation>
|
66
|
+
The Atom feed construct is defined in section 4.1.1 of the format spec.
|
67
|
+
</xs:documentation>
|
68
|
+
</xs:annotation>
|
69
|
+
<xs:choice minOccurs="3" maxOccurs="unbounded">
|
70
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
71
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded" />
|
72
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
73
|
+
<xs:element name="generator" type="atom:generatorType" minOccurs="0" maxOccurs="1" />
|
74
|
+
<xs:element name="icon" type="atom:iconType" minOccurs="0" maxOccurs="1" />
|
75
|
+
<xs:element name="id" type="atom:idType" minOccurs="1" maxOccurs="1" />
|
76
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded" />
|
77
|
+
<xs:element name="logo" type="atom:logoType" minOccurs="0" maxOccurs="1" />
|
78
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
79
|
+
<xs:element name="subtitle" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
80
|
+
<xs:element name="title" type="atom:textType" minOccurs="1" maxOccurs="1" />
|
81
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="1" maxOccurs="1" />
|
82
|
+
<xs:element name="entry" type="atom:entryType" minOccurs="0" maxOccurs="unbounded" />
|
83
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
84
|
+
</xs:choice>
|
85
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
86
|
+
</xs:complexType>
|
87
|
+
<xs:complexType name="entryType">
|
88
|
+
<xs:annotation>
|
89
|
+
<xs:documentation>
|
90
|
+
The Atom entry construct is defined in section 4.1.2 of the format spec.
|
91
|
+
</xs:documentation>
|
92
|
+
</xs:annotation>
|
93
|
+
<xs:choice maxOccurs="unbounded">
|
94
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
95
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded" />
|
96
|
+
<xs:element name="content" type="atom:contentType" minOccurs="0" maxOccurs="1" />
|
97
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded" />
|
98
|
+
<xs:element name="id" type="atom:idType" minOccurs="1" maxOccurs="1" />
|
99
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded" />
|
100
|
+
<xs:element name="published" type="atom:dateTimeType" minOccurs="0" maxOccurs="1" />
|
101
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
102
|
+
<xs:element name="source" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
103
|
+
<xs:element name="summary" type="atom:textType" minOccurs="0" maxOccurs="1" />
|
104
|
+
<xs:element name="title" type="atom:textType" minOccurs="1" maxOccurs="1" />
|
105
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="1" maxOccurs="1" />
|
106
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
107
|
+
</xs:choice>
|
108
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
109
|
+
</xs:complexType>
|
110
|
+
<xs:complexType name="contentType" mixed="true">
|
111
|
+
<xs:annotation>
|
112
|
+
<xs:documentation>
|
113
|
+
The Atom content construct is defined in section 4.1.3 of the format spec.
|
114
|
+
</xs:documentation>
|
115
|
+
</xs:annotation>
|
116
|
+
<xs:sequence>
|
117
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
|
118
|
+
</xs:sequence>
|
119
|
+
<xs:attribute name="type" type="xs:string"/>
|
120
|
+
<xs:attribute name="src" type="xs:anyURI"/>
|
121
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
122
|
+
</xs:complexType>
|
123
|
+
<xs:complexType name="categoryType">
|
124
|
+
<xs:annotation>
|
125
|
+
<xs:documentation>
|
126
|
+
The Atom cagegory construct is defined in section 4.2.2 of the format spec.
|
127
|
+
</xs:documentation>
|
128
|
+
</xs:annotation>
|
129
|
+
<xs:attribute name="term" type="xs:string" use="required"/>
|
130
|
+
<xs:attribute name="scheme" type="xs:anyURI" use="optional"/>
|
131
|
+
<xs:attribute name="label" type="xs:string" use="optional"/>
|
132
|
+
<xs:attributeGroup ref="atom:commonAttributes" />
|
133
|
+
</xs:complexType>
|
134
|
+
<xs:complexType name="generatorType">
|
135
|
+
<xs:annotation>
|
136
|
+
<xs:documentation>
|
137
|
+
The Atom generator element is defined in section 4.2.4 of the format spec.
|
138
|
+
</xs:documentation>
|
139
|
+
</xs:annotation>
|
140
|
+
<xs:simpleContent>
|
141
|
+
<xs:extension base="xs:string">
|
142
|
+
<xs:attribute name="uri" use="optional" type="xs:anyURI" />
|
143
|
+
<xs:attribute name="version" use="optional" type="xs:string" />
|
144
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
145
|
+
</xs:extension>
|
146
|
+
</xs:simpleContent>
|
147
|
+
</xs:complexType>
|
148
|
+
<xs:complexType name="iconType">
|
149
|
+
<xs:annotation>
|
150
|
+
<xs:documentation>
|
151
|
+
The Atom icon construct is defined in section 4.2.5 of the format spec.
|
152
|
+
</xs:documentation>
|
153
|
+
</xs:annotation>
|
154
|
+
<xs:simpleContent>
|
155
|
+
<xs:extension base="xs:anyURI">
|
156
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
157
|
+
</xs:extension>
|
158
|
+
</xs:simpleContent>
|
159
|
+
</xs:complexType>
|
160
|
+
<xs:complexType name="idType">
|
161
|
+
<xs:annotation>
|
162
|
+
<xs:documentation>
|
163
|
+
The Atom id construct is defined in section 4.2.6 of the format spec.
|
164
|
+
</xs:documentation>
|
165
|
+
</xs:annotation>
|
166
|
+
<xs:simpleContent>
|
167
|
+
<xs:extension base="xs:anyURI">
|
168
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
169
|
+
</xs:extension>
|
170
|
+
</xs:simpleContent>
|
171
|
+
</xs:complexType>
|
172
|
+
<xs:complexType name="linkType" mixed="true">
|
173
|
+
<xs:annotation>
|
174
|
+
<xs:documentation>
|
175
|
+
The Atom link construct is defined in section 3.4 of the format spec.
|
176
|
+
</xs:documentation>
|
177
|
+
</xs:annotation>
|
178
|
+
<xs:attribute name="href" use="required" type="xs:anyURI" />
|
179
|
+
<xs:attribute name="rel" type="xs:string" use="optional"/>
|
180
|
+
<xs:attribute name="type" use="optional" type="xs:string" />
|
181
|
+
<xs:attribute name="hreflang" use="optional" type="xs:NMTOKEN" />
|
182
|
+
<xs:attribute name="title" use="optional" type="xs:string" />
|
183
|
+
<xs:attribute name="length" use="optional" type="xs:positiveInteger" />
|
184
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
185
|
+
</xs:complexType>
|
186
|
+
<xs:complexType name="logoType">
|
187
|
+
<xs:annotation>
|
188
|
+
<xs:documentation>
|
189
|
+
The Atom logo construct is defined in section 4.2.8 of the format spec.
|
190
|
+
</xs:documentation>
|
191
|
+
</xs:annotation>
|
192
|
+
<xs:simpleContent>
|
193
|
+
<xs:extension base="xs:anyURI">
|
194
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
195
|
+
</xs:extension>
|
196
|
+
</xs:simpleContent>
|
197
|
+
</xs:complexType>
|
198
|
+
<xs:complexType name="sourceType">
|
199
|
+
<xs:annotation>
|
200
|
+
<xs:documentation>
|
201
|
+
The Atom source construct is defined in section 4.2.11 of the format spec.
|
202
|
+
</xs:documentation>
|
203
|
+
</xs:annotation>
|
204
|
+
<xs:choice maxOccurs="unbounded">
|
205
|
+
<xs:element name="author" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
|
206
|
+
<xs:element name="category" type="atom:categoryType" minOccurs="0" maxOccurs="unbounded"/>
|
207
|
+
<xs:element name="contributor" type="atom:personType" minOccurs="0" maxOccurs="unbounded"/>
|
208
|
+
<xs:element name="generator" type="atom:generatorType" minOccurs="0" maxOccurs="1"/>
|
209
|
+
<xs:element name="icon" type="atom:iconType" minOccurs="0" maxOccurs="1"/>
|
210
|
+
<xs:element name="id" type="atom:idType" minOccurs="0" maxOccurs="1"/>
|
211
|
+
<xs:element name="link" type="atom:linkType" minOccurs="0" maxOccurs="unbounded"/>
|
212
|
+
<xs:element name="logo" type="atom:logoType" minOccurs="0" maxOccurs="1"/>
|
213
|
+
<xs:element name="rights" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
214
|
+
<xs:element name="subtitle" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
215
|
+
<xs:element name="title" type="atom:textType" minOccurs="0" maxOccurs="1"/>
|
216
|
+
<xs:element name="updated" type="atom:dateTimeType" minOccurs="0" maxOccurs="1"/>
|
217
|
+
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
|
218
|
+
</xs:choice>
|
219
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
220
|
+
</xs:complexType>
|
221
|
+
<xs:complexType name="uriType">
|
222
|
+
<xs:simpleContent>
|
223
|
+
<xs:extension base="xs:anyURI">
|
224
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
225
|
+
</xs:extension>
|
226
|
+
</xs:simpleContent>
|
227
|
+
</xs:complexType>
|
228
|
+
<xs:complexType name="dateTimeType">
|
229
|
+
<xs:simpleContent>
|
230
|
+
<xs:extension base="xs:dateTime">
|
231
|
+
<xs:attributeGroup ref="atom:commonAttributes"/>
|
232
|
+
</xs:extension>
|
233
|
+
</xs:simpleContent>
|
234
|
+
</xs:complexType>
|
235
|
+
<xs:attributeGroup name="commonAttributes">
|
236
|
+
<xs:attribute ref="xml:base" />
|
237
|
+
<xs:attribute ref="xml:lang" />
|
238
|
+
<xs:anyAttribute namespace="##other"/>
|
239
|
+
</xs:attributeGroup>
|
240
|
+
</xs:schema>
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Atom feed building' do
|
4
|
+
let(:feed) do
|
5
|
+
Xommelier::Atom::Feed.new.tap do |feed|
|
6
|
+
feed.id = 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6'
|
7
|
+
feed.title = 'Example Feed'
|
8
|
+
feed.link = Xommelier::Atom::Link.new(href: 'http://example.org/')
|
9
|
+
feed.updated = Time.utc(2003, 12, 13, 18, 30, 02)
|
10
|
+
feed.author = Xommelier::Atom::Person.new(name: 'John Doe')
|
11
|
+
feed.entry = Xommelier::Atom::Entry.new(
|
12
|
+
title: 'Atom-Powered Robots Run Amok',
|
13
|
+
id: 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a',
|
14
|
+
updated: Time.utc(2003, 12, 13, 18, 30, 02),
|
15
|
+
summary: 'Some text.'
|
16
|
+
).tap do |entry|
|
17
|
+
entry.link = Xommelier::Atom::Link.new(href: 'http://example.org/2003/12/13/atom03')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:built_xml) { feed.to_xml }
|
23
|
+
let(:parsed_xml) { Nokogiri::XML(built_xml) }
|
24
|
+
let(:rng) { Nokogiri::XML::RelaxNG(load_xml_file('atom.rng')) }
|
25
|
+
let(:xsd) { Nokogiri::XML::Schema(load_xml_file('atom.xsd')) }
|
26
|
+
|
27
|
+
subject { built_xml }
|
28
|
+
|
29
|
+
it { should == load_xml_file('simple_feed.atom').read }
|
30
|
+
it('should conform to RelaxNG schema') { rng.valid?(parsed_xml).should == true }
|
31
|
+
it('should conform to XML Schema') { xsd.valid?(parsed_xml).should == true }
|
32
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'active_support/core_ext/numeric/time'
|
4
|
+
|
5
|
+
describe 'Atom feed' do
|
6
|
+
describe 'parsing' do
|
7
|
+
let(:atom_xml) { load_xml_file('feed.atom') }
|
8
|
+
let(:feed) { Xommelier::Atom::Feed.parse(atom_xml) }
|
9
|
+
|
10
|
+
subject { feed }
|
11
|
+
|
12
|
+
it { should be_kind_of(Xommelier::Atom::Feed) }
|
13
|
+
|
14
|
+
its(:id) { should == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' }
|
15
|
+
its(:title) { should == 'Example Feed' }
|
16
|
+
its(:updated) { should == Time.utc(2003, 12, 13, 18, 30, 02) }
|
17
|
+
its(:subtitle) { should == 'A <em>lot</em> of effort went into making this effortless' }
|
18
|
+
|
19
|
+
it { should have(2).links }
|
20
|
+
its(:link) { should be_instance_of(Xommelier::Atom::Link) }
|
21
|
+
it { feed.links[0].href.should == URI.parse('http://example.ru/') }
|
22
|
+
it { feed.links[0].rel.should == 'alternate' }
|
23
|
+
it { feed.links[0].type.should == 'text/html' }
|
24
|
+
it { feed.links[1].href.should == URI.parse('http://example.ru/feed.atom') }
|
25
|
+
it { feed.links[1].rel.should == 'self' }
|
26
|
+
it { feed.links[1].type.should == 'application/atom+xml' }
|
27
|
+
|
28
|
+
its(:rights) { should == '© Mark Pilgrim, 2003' }
|
29
|
+
describe 'Generator' do
|
30
|
+
subject { feed.generator }
|
31
|
+
pending 'Make Xommelier::Xml::Element.to_s respond with #text.to_s' do
|
32
|
+
it { should == 'Example Toolkit' }
|
33
|
+
its(:text) { should == 'Example Toolkit' }
|
34
|
+
end
|
35
|
+
its(:uri) { should == URI.parse('http://example.com/') }
|
36
|
+
its(:version) { should == '1.0' }
|
37
|
+
end
|
38
|
+
|
39
|
+
it { should have(1).authors }
|
40
|
+
its(:author) { should be_instance_of(Xommelier::Atom::Person) }
|
41
|
+
it { feed.author.name.should == 'John Doe' }
|
42
|
+
|
43
|
+
it { feed.should have(1).entries }
|
44
|
+
describe 'Entry' do
|
45
|
+
let(:entry) { feed.entry }
|
46
|
+
subject { entry }
|
47
|
+
|
48
|
+
its(:id) { should == 'urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a' }
|
49
|
+
its(:title) { should == 'Atom-Powered Robots Run Amok' }
|
50
|
+
its(:updated) { should == Time.utc(2003, 12, 13, 18, 30, 02) }
|
51
|
+
its(:published) { should == Time.utc(2003, 12, 13, 8, 29, 29) + 4.hours }
|
52
|
+
|
53
|
+
it { should have(2).links }
|
54
|
+
its(:link) { should be_instance_of(Xommelier::Atom::Link) }
|
55
|
+
it { entry.links[0].href.should == URI.parse('http://example.ru/2003/12/13/atom03') }
|
56
|
+
it { entry.links[0].rel.should == 'alternate' }
|
57
|
+
it { entry.links[0].type.should == 'text/html' }
|
58
|
+
it { entry.links[1].href.should == URI.parse('http://example.org/audio/ph34r_my_podcast.mp3') }
|
59
|
+
it { entry.links[1].rel.should == 'enclosure' }
|
60
|
+
it { entry.links[1].type.should == 'audio/mpeg' }
|
61
|
+
it { entry.links[1].length.should == 1337 }
|
62
|
+
|
63
|
+
it { should have(1).authors }
|
64
|
+
|
65
|
+
describe 'Author' do
|
66
|
+
subject { entry.author }
|
67
|
+
its(:name) { should == 'Mark Pilgrim'}
|
68
|
+
its(:uri) { should == URI.parse('http://example.org/') }
|
69
|
+
its(:email) { should == 'f8dy@example.com' }
|
70
|
+
end
|
71
|
+
|
72
|
+
it { should have(2).contributors }
|
73
|
+
it { entry.contributors[0].name.should == 'Sam Ruby' }
|
74
|
+
it { entry.contributors[1].name.should == 'Joe Gregorio' }
|
75
|
+
its(:summary) { should == 'Some text.' }
|
76
|
+
its(:content) { should ~ /#{Regexp.escape('[Update: The Atom draft is fiished.]')}/ }
|
77
|
+
pending 'should parse text-based elements\' attributes' do
|
78
|
+
subject { entry.content }
|
79
|
+
its(:type) { should == 'xhtml' }
|
80
|
+
its(:lang) { should == 'en' }
|
81
|
+
its(:base) { should == 'http://diveintomark.org/' }
|
82
|
+
its(:content) { should ~ /#{Regexp.escape('<p><i>[Update: The Atom draft is fiished.]</i></p>')}/ }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -8,7 +8,7 @@ describe Xommelier::Xml::Element::Serialization do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe 'parsing simple_feed' do
|
11
|
-
let(:feed) { @feed = Xommelier::Atom::Feed.parse(
|
11
|
+
let(:feed) { @feed = Xommelier::Atom::Feed.parse(load_xml_file('simple_feed.atom')) }
|
12
12
|
|
13
13
|
it { feed.id.should == 'urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6' }
|
14
14
|
it { feed.title.should == 'Example Feed' }
|
@@ -23,14 +23,4 @@ describe Xommelier::Xml::Element::Serialization do
|
|
23
23
|
it { feed.entry.updated.should == Time.utc(2003, 12, 13, 18, 30, 02) }
|
24
24
|
it { feed.entry.summary.should == 'Some text.' }
|
25
25
|
end
|
26
|
-
|
27
|
-
describe 'parsing feed' do
|
28
|
-
let(:feed) { Xommelier::Atom::Feed.parse(open(File.join(SPEC_ROOT, 'spec', 'fixtures', 'feed.atom'))) }
|
29
|
-
|
30
|
-
it { feed.should have(2).links }
|
31
|
-
it { feed.subtitle.should == 'A <em>lot</em> of effort went into making this effortless' }
|
32
|
-
it { feed.entry.should have(2).links }
|
33
|
-
it { feed.entry.should have(1).authors }
|
34
|
-
it { feed.entry.should have(2).contributors }
|
35
|
-
end
|
36
26
|
end
|
data/xommelier.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.authors = ["Alexander Semyonov"]
|
9
9
|
s.email = ["al@semyonov.us"]
|
10
10
|
s.homepage = "http://github.com/alsemyonov/xommelier"
|
11
|
-
s.summary = %q{XML
|
11
|
+
s.summary = %q{Xommelier is an XML Sommelier}
|
12
12
|
s.description = %q{XML-Object Mapper with many built-in XML formats supported}
|
13
13
|
|
14
14
|
s.rubyforge_project = "xommelier"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xommelier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-03-04 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &70260929846960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.5.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70260929846960
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
27
|
-
requirement: &
|
27
|
+
requirement: &70260929843940 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.2.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70260929843940
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: activemodel
|
38
|
-
requirement: &
|
38
|
+
requirement: &70260929842860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 3.2.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70260929842860
|
47
47
|
description: XML-Object Mapper with many built-in XML formats supported
|
48
48
|
email:
|
49
49
|
- al@semyonov.us
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- .rspec
|
56
56
|
- Gemfile
|
57
57
|
- Guardfile
|
58
|
+
- MIT-LICENSE
|
58
59
|
- README.md
|
59
60
|
- Rakefile
|
60
61
|
- Termfile
|
@@ -88,8 +89,12 @@ files:
|
|
88
89
|
- lib/xommelier/xml/element/serialization.rb
|
89
90
|
- lib/xommelier/xml/element/structure.rb
|
90
91
|
- lib/xommelier/xml/namespace.rb
|
91
|
-
- spec/fixtures/
|
92
|
-
- spec/fixtures/
|
92
|
+
- spec/fixtures/atom.rng.xml
|
93
|
+
- spec/fixtures/atom.xsd.xml
|
94
|
+
- spec/fixtures/feed.atom.xml
|
95
|
+
- spec/fixtures/simple_feed.atom.xml
|
96
|
+
- spec/functional/atom_feed_building_spec.rb
|
97
|
+
- spec/functional/atom_feed_parsing_spec.rb
|
93
98
|
- spec/lib/xommelier/atom/entry_spec.rb
|
94
99
|
- spec/lib/xommelier/xml/element/serialization_spec.rb
|
95
100
|
- spec/lib/xommelier/xml/element/structure_spec.rb
|
@@ -98,6 +103,7 @@ files:
|
|
98
103
|
- spec/lib/xommelier_spec.rb
|
99
104
|
- spec/namespaced_module.rb
|
100
105
|
- spec/spec_helper.rb
|
106
|
+
- spec/support/fixtures.rb
|
101
107
|
- xommelier.gemspec
|
102
108
|
homepage: http://github.com/alsemyonov/xommelier
|
103
109
|
licenses: []
|
@@ -122,10 +128,14 @@ rubyforge_project: xommelier
|
|
122
128
|
rubygems_version: 1.8.11
|
123
129
|
signing_key:
|
124
130
|
specification_version: 3
|
125
|
-
summary: XML
|
131
|
+
summary: Xommelier is an XML Sommelier
|
126
132
|
test_files:
|
127
|
-
- spec/fixtures/
|
128
|
-
- spec/fixtures/
|
133
|
+
- spec/fixtures/atom.rng.xml
|
134
|
+
- spec/fixtures/atom.xsd.xml
|
135
|
+
- spec/fixtures/feed.atom.xml
|
136
|
+
- spec/fixtures/simple_feed.atom.xml
|
137
|
+
- spec/functional/atom_feed_building_spec.rb
|
138
|
+
- spec/functional/atom_feed_parsing_spec.rb
|
129
139
|
- spec/lib/xommelier/atom/entry_spec.rb
|
130
140
|
- spec/lib/xommelier/xml/element/serialization_spec.rb
|
131
141
|
- spec/lib/xommelier/xml/element/structure_spec.rb
|
@@ -134,4 +144,5 @@ test_files:
|
|
134
144
|
- spec/lib/xommelier_spec.rb
|
135
145
|
- spec/namespaced_module.rb
|
136
146
|
- spec/spec_helper.rb
|
147
|
+
- spec/support/fixtures.rb
|
137
148
|
has_rdoc:
|
File without changes
|
@@ -9,9 +9,9 @@
|
|
9
9
|
</author>
|
10
10
|
<entry>
|
11
11
|
<title>Atom-Powered Robots Run Amok</title>
|
12
|
-
<link href="http://example.org/2003/12/13/atom03"/>
|
13
12
|
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
|
14
13
|
<updated>2003-12-13T18:30:02Z</updated>
|
15
14
|
<summary>Some text.</summary>
|
15
|
+
<link href="http://example.org/2003/12/13/atom03"/>
|
16
16
|
</entry>
|
17
17
|
</feed>
|