338 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
		
			Executable File
		
	
	
	
	
| # -*- 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 |