-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom_feed.rnc
186 lines (137 loc) · 6.31 KB
/
atom_feed.rnc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# -*- rnc -*-
# RELAX NG Compact Syntax Grammar for the
# Atom Format Specification
# Taken from http://tools.ietf.org/html/rfc4287#page-35
# Defined a new constructor for ATOM Feed and Entry
#
# Version: 1.0.0
#
namespace atom = "http://www.w3.org/2005/Atom"
namespace xhtml = "http://www.w3.org/1999/xhtml"
namespace s = "http://purl.oclc.org/dsdl/schematron"
namespace local = ""
start = atomFeed | atomEntry
# Common attributes
atomCommonAttributes = attribute xml:base { atomUri }?,
attribute xml:lang { atomLanguageTag }?, undefinedAttribute*
# Text Constructs
atomPlainTextConstruct = atomCommonAttributes, attribute type { "text" | "html" }?, text
atomXHTMLTextConstruct = atomCommonAttributes, attribute type { "xhtml" }, xhtmlDiv
atomTextConstruct = atomPlainTextConstruct | atomXHTMLTextConstruct
# Person Construct
atomPersonConstruct = atomCommonAttributes,
(element atom:name { text } & element atom:uri { atomUri }?
& element atom:email { atomEmailAddress }? & extensionElement*)
# Date Construct
atomDateConstruct = atomCommonAttributes, xsd:dateTime
# atom:feed
atomFeed = [
s:pattern [ name="check authors"
s:rule [ context = "atom:feed"
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." ]]]]
element atom:feed { atomFeedConstruct }
atomFeedConstruct =
atomCommonAttributes, (atomAuthor* & atomCategory* & atomContributor*
& atomGenerator? & atomIcon? & atomId & atomLink* & atomLogo? & atomRights? &
atomSubtitle? & atomTitle & atomUpdated & extensionElement*), atomEntry*
# atom:entry
atomEntry = [
s:pattern [ name="check entry's alternate link"
s:rule [ context = "atom:entry" 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:pattern [ name="check entry's author"
s:rule [ context = "atom:entry" 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."
]]]]
element atom:entry { atomEntryConstruct }
atomEntryConstruct =
atomCommonAttributes,
(atomAuthor* & atomCategory* & atomContent? & atomContributor*
& atomId & atomLink* & atomPublished? & atomRights? & atomSource?
& atomSummary? & atomTitle & atomUpdated & extensionElement*)
# atom:content
atomInlineTextContent = element atom:content { atomCommonAttributes,
attribute type { "text" | "html" }?, (text)* }
atomInlineXHTMLContent = element atom:content { atomCommonAttributes,
attribute type { "xhtml" }, xhtmlDiv }
atomInlineOtherContent = element atom:content { atomCommonAttributes,
attribute type { atomMediaType }?, (text|anyElement)*}
atomOutOfLineContent = element atom:content { atomCommonAttributes,
attribute type { atomMediaType }?, attribute src { atomUri }, empty }
atomContent = atomInlineTextContent | atomInlineXHTMLContent
| atomInlineOtherContent | atomOutOfLineContent
# atom:author
atomAuthor = element atom:author { atomPersonConstruct }
# atom:category
atomCategory =
element atom:category { atomCommonAttributes, attribute term { text },
attribute scheme { atomUri }?, attribute label { text }?,
undefinedContent}
# atom:contributor
atomContributor = element atom:contributor { atomPersonConstruct }
# atom:generator
atomGenerator = element atom:generator { atomCommonAttributes,
attribute uri { atomUri }?, attribute version { text }?, text }
# atom:icon
atomIcon = element atom:icon { atomCommonAttributes, (atomUri) }
# atom:id
atomId = element atom:id { atomCommonAttributes, (atomUri) }
# atom:logo
atomLogo = element atom:logo { atomCommonAttributes, (atomUri)}
# atom:link
atomLink =
element atom:link { atomCommonAttributes, attribute href { atomUri },
attribute rel { atomNCName | atomUri }?, attribute type { atomMediaType }?,
attribute hreflang { atomLanguageTag }?, attribute title { text }?,
attribute length { text }?, undefinedContent}
# atom:published
atomPublished = element atom:published { atomDateConstruct }
# atom:rights
atomRights = element atom:rights { atomTextConstruct }
# atom:source
atomSource = element atom:source {
atomCommonAttributes, (atomAuthor* & atomCategory* & atomContributor* &
atomGenerator? & atomIcon? & atomId? & atomLink* & atomLogo? & atomRights?
& atomSubtitle? & atomTitle? & atomUpdated? & extensionElement*)}
# atom:subtitle
atomSubtitle = element atom:subtitle { atomTextConstruct }
# atom:summary
atomSummary = element atom:summary { atomTextConstruct }
# atom:title
atomTitle = element atom:title { atomTextConstruct }
# atom:updated
atomUpdated = element atom:updated { atomDateConstruct }
# Low-level simple types
atomNCName = xsd:string { minLength = "1" pattern = "[^:]*" }
# Whatever a media type is, it contains at least one slash
atomMediaType = xsd:string { pattern = ".+/.+" }
# As defined in RFC 3066
atomLanguageTag = xsd:string { pattern = "[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*"}
# Unconstrained; it's not entirely clear how IRI fit into
# xsd:anyURI so let's not try to constrain it here
atomUri = text
# Whatever an email address is, it contains at least one @
atomEmailAddress = xsd:string { pattern = ".+@.+" }
# Simple Extension
simpleExtensionElement = element * - atom:* { text }
# Structured Extension
structuredExtensionElement = element * - atom:* {
(attribute * { text }+, (text|anyElement)*)
| (attribute * { text }*, (text?, anyElement+, (text|anyElement)*))}
# Other Extensibility
extensionElement = simpleExtensionElement | structuredExtensionElement
undefinedAttribute = attribute * - (xml:base | xml:lang | local:*) { text }
undefinedContent = (text|anyForeignElement)*
anyElement = element * { (attribute * { text } | text | anyElement)* }
anyForeignElement = element * - atom:* { (attribute * { text } | text | anyElement)* }
# XHTML
anyXHTML = element xhtml:* { (attribute * { text } | text | anyXHTML)* }
xhtmlDiv = element xhtml:div { (attribute * { text } | text | anyXHTML)* }
# EOF