cops/test/res/atom.rnc

339 lines
6.6 KiB
Plaintext

# -*- rnc -*-
# RELAX NG Compact Syntax Grammar for the
# Atom Format Specification Version 11
namespace atom = "http://www.w3.org/2005/Atom"
namespace xhtml = "http://www.w3.org/1999/xhtml"
namespace s = "http://www.ascc.net/xml/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: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 {
atomCommonAttributes,
(atomAuthor*
& atomCategory*
& atomContributor*
& atomGenerator?
& atomIcon?
& atomId
& atomLink*
& atomLogo?
& atomRights?
& atomSubtitle?
& atomTitle
& atomUpdated
& extensionElement*),
atomEntry*
}
# atom:entry
atomEntry =
[
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: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 {
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