2 # RELAX NG Compact Syntax Grammar for the
3 # Atom Format Specification Version 11
5 namespace atom = "http://www.w3.org/2005/Atom"
6 namespace xhtml = "http://www.w3.org/1999/xhtml"
7 namespace s = "http://www.ascc.net/xml/schematron"
10 start = atomFeed | atomEntry
14 atomCommonAttributes =
15 attribute xml:base { atomUri }?,
16 attribute xml:lang { atomLanguageTag }?,
21 atomPlainTextConstruct =
23 attribute type { "text" | "html" }?,
26 atomXHTMLTextConstruct =
28 attribute type { "xhtml" },
31 atomTextConstruct = atomPlainTextConstruct | atomXHTMLTextConstruct
37 (element atom:name { text }
38 & element atom:uri { atomUri }?
39 & element atom:email { atomEmailAddress }?
55 test = "atom:author or not(atom:entry[not(atom:author)])"
56 "An atom:feed must have an atom:author unless all "
57 ~ "of its atom:entry children have an atom:author."
84 context = "atom:entry"
86 test = "atom:link[@rel='alternate'] "
87 ~ "or atom:link[not(@rel)] "
89 "An atom:entry must have at least one atom:link element "
90 ~ "with a rel attribute of 'alternate' "
91 ~ "or an atom:content."
95 context = "atom:entry"
97 test = "atom:author or "
98 ~ "../atom:author or atom:source/atom:author"
99 "An atom:entry must have an atom:author "
100 ~ "if its feed does not."
105 atomCommonAttributes,
123 atomInlineTextContent =
124 element atom:content {
125 atomCommonAttributes,
126 attribute type { "text" | "html" }?,
130 atomInlineXHTMLContent =
131 element atom:content {
132 atomCommonAttributes,
133 attribute type { "xhtml" },
137 atomInlineOtherContent =
138 element atom:content {
139 atomCommonAttributes,
140 attribute type { atomMediaType }?,
144 atomOutOfLineContent =
145 element atom:content {
146 atomCommonAttributes,
147 attribute type { atomMediaType }?,
148 attribute src { atomUri },
152 atomContent = atomInlineTextContent
153 | atomInlineXHTMLContent
154 | atomInlineOtherContent
155 | atomOutOfLineContent
159 atomAuthor = element atom:author { atomPersonConstruct }
164 element atom:category {
165 atomCommonAttributes,
166 attribute term { text },
167 attribute scheme { atomUri }?,
168 attribute label { text }?,
174 atomContributor = element atom:contributor { atomPersonConstruct }
178 atomGenerator = element atom:generator {
179 atomCommonAttributes,
180 attribute uri { atomUri }?,
181 attribute version { text }?,
187 atomIcon = element atom:icon {
188 atomCommonAttributes,
194 atomId = element atom:id {
195 atomCommonAttributes,
201 atomLogo = element atom:logo {
202 atomCommonAttributes,
210 atomCommonAttributes,
211 attribute href { atomUri },
212 attribute rel { atomNCName | atomUri }?,
213 attribute type { atomMediaType }?,
214 attribute hreflang { atomLanguageTag }?,
215 attribute title { text }?,
216 attribute length { text }?,
222 atomPublished = element atom:published { atomDateConstruct }
226 atomRights = element atom:rights { atomTextConstruct }
231 element atom:source {
232 atomCommonAttributes,
250 atomSubtitle = element atom:subtitle { atomTextConstruct }
254 atomSummary = element atom:summary { atomTextConstruct }
258 atomTitle = element atom:title { atomTextConstruct }
262 atomUpdated = element atom:updated { atomDateConstruct }
264 # Low-level simple types
266 atomNCName = xsd:string { minLength = "1" pattern = "[^:]*" }
268 # Whatever a media type is, it contains at least one slash
269 atomMediaType = xsd:string { pattern = ".+/.+" }
271 # As defined in RFC 3066
272 atomLanguageTag = xsd:string {
273 pattern = "[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*"
276 # Unconstrained; it's not entirely clear how IRI fit into
277 # xsd:anyURI so let's not try to constrain it here
280 # Whatever an email address is, it contains at least one @
281 atomEmailAddress = xsd:string { pattern = ".+@.+" }
285 simpleExtensionElement =
290 # Structured Extension
292 structuredExtensionElement =
294 (attribute * { text }+,
296 | (attribute * { text }*,
297 (text?, anyElement+, (text|anyElement)*))
300 # Other Extensibility
303 simpleExtensionElement | structuredExtensionElement
306 attribute * - (xml:base | xml:lang | local:*) { text }
308 undefinedContent = (text|anyForeignElement)*
312 (attribute * { text }
319 (attribute * { text }
326 anyXHTML = element xhtml:* {
327 (attribute * { text }
332 xhtmlDiv = element xhtml:div {
333 (attribute * { text }