Subject: Obs on format-07

From: Bill de hÓra <[email-masked]>
Date: Thu, 07 Apr 2005 02:50:31 +0100

Hi editors,

Comments and observations on the 07 draft.

** RNC Schema

- is valid rnc

- the schema and the fragments appear to be consistent.

- both examples validate according to the supplied schema

- the xhtml fragments in 4.1.3.4 validate when embedded as specified.

- in 6.4; simple and extension schema forbid the use of the atom 
namespace as the top level element in the extension. This is a very 
common RNG idiom and I imagine the text should reflect the constraint 
assuming that's the consensus of the WG. Note that it cannot generally 
be represented in WXS; for example, Trang will convert it to a looser 
xsd:any constraint.

- in 6.4; extension schema allow the use of the atom namespace as child 
elements of the extension. I do not recall this being discussed, but 
personally am +1 to it.

- I believe atomfeed and

replace:
[[[
App B Collected RELAX NG Compact Schema
]]]

with:
"App B RELAX NG Compact Schema"

reason: not all the schema is presented in fragment form, so the title 
is incorrect.

** 1. Introduction

p2. the last sentence requires a for-example or should be struck.

reason: qualify what 'other purposes' might be.

** 1.1 Examples:

Please use a namespace prefix for both or at least one of the examples.

reason: 1) default namespaces are not robust (I offer requirement of 
xhtml:div as evidence), examples in XML formats should not propagate the 
practice. 2) example markup is not consistent with naming convention 
used to call out specified elements.

Please add a element property to an entry that is not from the format 
(ie Dublin Core)

reason: demonstrate what extensible indicates upfront.

** 2. Atom Documents

p5: this paragraph can be struck without loss of meaning.

reason: adds no specification value.

p8: replace:
[[[
Atom allows the use of IRIs [RFC3987], as well as URIs [RFC3986]. For 
resolution, IRIs can easily be converted to URIs. When comparing IRIs 
serving as atom:id values, they MUST NOT be converted to URIs. By 
definition, every URI is an IRI, so any URI can be used where an IRI is 
needed.
]]]

with the following:

"Atom allows the use of IRIs [RFC3987], as well as URIs [RFC3986]. By 
definition, every URI is an IRI, so any URI can be used where an IRI is 
needed. Note:

  1. For purposes of resolution, IRIs MAY be converted to URIs.

  2. For purposes of comparison, where IRIs act as atom:id values, they 
MUST NOT be converted to URIs."

Also, if 'resolution' is a term taken from some spec it should be called 
out as such.

reason: p8 does not read clearly enough to provide implementor guidance.

ob: I think this indicates an implementor burden of using IRIs. I need 
to write conversion code differently depending on whether I'm resolving 
or comparing.

p10: remove the following clause:
[[[but may be defined by an extension to Atom.]]]

reason: the caveat adds no specification value and provides questions 
without answers (does 'may' mean 'might' above? defined by who? etc).

** 3.1.1 The "type" Attribute

replace:
[[[
Note that MIME media types [RFC2045] are not acceptable values for the 
"type" attribute.
]]]

with:

"MIME media types [RFC2045] MUST NOT be used as values for the "type" 
attribute."

reason: state the specification as specification not as a side note.

** 3.1.1.3 XHTML

replace
[[[
The following example assumes that the XHTML namespace has been bound to 
the "xh" prefix earlier in the document:
]]]

with

"Note: the following example is not well formed unless the XHTML 
namespace has been bound previously  to the "xh" prefix in the document:"

reason: clearly indicate what conformance prefix binding entails.

** 4.1.1 The "atom:feed" Element

replace:
[[[
* atom:feed elements MUST contain exactly one atom:author element, 
UNLESS all of the atom:feed element's child atom:entry elements contain 
an atom:author element. atom:feed elements MUST NOT contain more than 
one atom:author element.
]]]

with:
"* atom:feed elements MUST contain an atom:author element, UNLESS all of 
the atom:feed element's child atom:entry elements contain an atom:author 
element.

* atom:feed elements MUST NOT contain more than one atom:author element."

reason: give each spec its own bullet point.

replace:
[[[
* atom:feed elements MUST NOT contain more than one atom:link element 
with a rel attribute value of "alternate" that has the same type 
attribute value. If a feed's atom:link element with type="alternate" 
resolves to an HTML document, then that document SHOULD have a 
autodiscovery link element [Atom-autodiscovery] that reflects back to 
the feed. atom:feed elements MAY contain additional atom:link elements 
beyond those described above.
]]]

with:
"* atom:feed elements MUST NOT contain more than one atom:link element 
with a rel attribute value of "alternate" which have the same type 
attribute value.

* If a feed's atom:link element with type="alternate" resolves to an 
HTML document, then that document SHOULD have a autodiscovery link 
element [Atom-autodiscovery] that reflects back to the feed.

* atom:feed elements MAY contain additional atom:link elements with 
values of the rel attribute other than 'alternate' and 'self'."

reason: give each spec its own bullet point. Change "that has" to "which 
have" as we're dealing with plurals.

** 4.1.2 The "atom:entry" Element

replace:
[[[
* atom:entry elements MUST contain exactly one atom:author element, 
unless the atom:entry contains an atom:source element which contains an 
atom:author element, or, in an Atom Feed Document, the atom:feed element 
contains an atom:author element itself. atom:entry elements MUST NOT 
contain more than one atom:author element.
]]]

with:
"* atom:entry elements MUST contain exactly one atom:author element, 
unless the atom:entry contains an atom:source element which contains an 
atom:author element, or, in an Atom Feed Document, the atom:feed element 
contains an atom:author element itself.

* atom:entry elements MUST NOT contain more than one atom:author element."

reason: give each spec its own bullet point.

replace:
[[[
* atom:entry elements that contain no child atom:content element MUST 
contain at least one atom:link element with a rel attribute value of 
"alternate". atom:entry elements MUST NOT contain more than one 
atom:link element with a rel attribute value of "alternate" that has the 
same combination of type and hreflang attribute values. atom:entry 
elements MAY contain additional atom:link elements beyond those 
described above.
]]]

with:
"* atom:entry elements that contain no child atom:content element MUST 
contain at least one atom:link element with a rel attribute value of 
"alternate".

* atom:entry elements MUST NOT contain more than one atom:link element 
with a rel attribute value of "alternate" which have the same 
combination of type and hreflang attribute values.

* atom:entry elements MAY contain additional atom:link elements with 
values of the rel attribute other than 'alternate'."

reason: give each spec its own bullet point. Change "that has" to "which 
have" as we're dealing with plurals.

** 4.2.7 The "atom:id" Element

replace:
[[[
Because of the risk of confusion between IRIs that would be equivalent 
if dereferenced, the following normalization strategy is strongly 
encouraged when generating atom:id elements:
]]]

with:
"Because of the risk of confusion between IRIs that would be equivalent 
if dereferenced, the following normalization strategy SHOULD be applied 
when generating atom:id elements:"
reason:

reason: prefer operational text; strongly encouraged sounds very like a 
SHOULD.

** 6.4.1 Simple Extension Elements

add:

add to end of para

"simpleExtensionElement =
    element * - atom:* {
       text
    }"

** 6.4.2 Structured Extension Elements

"structuredExtensionElement =
    element * - atom:* {
       (attribute * { text }+,
          (text|anyElement)*)
     | (attribute * { text }*,
        (text?, anyElement+, (text|anyElement)*))
    }"

** General **

** references

[Atom-autodiscovery]	Pilgrim, M., “Atom Feed Autodiscovery”, 
work-in-progress, August 2004.

I'm not sure Atom need be depending on this document. I probably missed 
that thread where we said it was ok.

add to the informative references:

[RELAX-NC]	OASIS Technical Committee: Committee Specification 21, “RELAX 
NG Compact Syntax”, November 2002.

fyi:http://www.oasis-open.org/committees/relax-ng/compact-20021121.html

** ABNF

Drop.

in 1.2, remove:
[[[
Some sections of this specification are illustrated with Augmented 
Backus-Naur Form (ABNF), a format used to represent permissible strings 
in a protocol or language, as defined in [RFC2234].
]]]

in 9.1 remove:

[[[
[RFC2234]  Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax 
Specifications: ABNF”, RFC 2234, November 1997.
]]

reason: ABNF is used in one place:

  4.2.9.2 The "rel" Attribute, p1

and referred to in 3.3. It's incidental enough to be dropped.

** Figures

Please add figure captions for all samples, bnf and rnc fragments. If 
you require someone to do this, I will do it.

** Replace specification keywords in lowercase (argghh!)

2. p10, "but may be defined by"

4.1.3.2, p1 "That is to say, the content may be retrievable usingThat is 
to say, the content may be retrievable using", "or it may be contained 
within atom:content, but not both."

4.1.3.3, bullet 2 " The XHTML div MUST contain XHTML text and markup 
that could validly"

bullet 4 "the content of atom:content may include child elements"

bullet 6 "the Base64 encoding may be preceded"

4.2.9.2 p4 bullet 4 "large in size and may require special handling"

5.1, p3, "the document element must not cause an Atom Processor"

6.2 p1 "versions of this specification may add new elements"

6.3 p1 "It may be the case" - replace 'may' with 'might' here

8.1 p1 "to receiving software, which may process it."

8.2 p2 "other elements may also have negative security properties" - 
replace 'may' with 'might' here

note: in some cases, may might be being used to indicate to indicate 
something is possible rather than something is permissable, I can 
determine that for sure in only two cases above; since may has a 
technical meaning, the editors should review the text and replace may 
with might as they see fit to avoid the idiomatic use of may as might.

---

From: Tim Bray <[email-masked]>
Date: Wed, 06 Apr 2005 19:11:05 -0700

> Comments and observations on the 07 draft.

Most seem OK to me, but...

> replace
> [[[
> The following example assumes that the XHTML namespace has been bound 
> to the "xh" prefix earlier in the document:
> ]]]
>
> with
>
> "Note: the following example is not well formed unless

In fact, it is "well-formed" if you are using that word in the 
technical XML sense; the definition of well-formedness does not forbid 
random colon prefixing.  I think this is OK left as is.  The meaning is 
entirely unambiguous. -Tim

---

From: Antone Roundy <[email-masked]>
Date: Wed, 6 Apr 2005 20:33:43 -0600

> namespace has been bound previously  to the "xh" prefix in the 

+1 to the concept, but perhaps it could be worded a little differently, 
eg. 'Note: the following example is only well formed if the XHTML 
namespace has been bound to the "xh" prefix earlier in the document.'  
If we want to be more verbose to be precise, we could add something to 
the effect that that namespace to prefix binding is in scope at this 
point in the document.  Reasons: 1) the first part of the sentence 
sounds like it's going to say that we're about to show an invalid 
example, and 2) "previously" (or "earlier") and "in the document" 
belong together.  Perhaps the editors would have tweaked it, but it 
doesn't hurt to comment...

> with a rel attribute value of "alternate" which have the same type 

Under atom:entry, we have: 'atom:entry elements MUST NOT contain more 
than one atom:link element with a rel attribute value of "alternate" 
that has the same combination of type and hreflang attribute values.'  
hreflang needs to be added under feed too, right?

> and referred to in 3.3. It's incidental enough to be dropped.

Not sure what you're referring to here.  Could you quote the text?

---

From: Sam Ruby <[email-masked]>
Date: Wed, 06 Apr 2005 23:02:05 -0400

An additional observation: neither of the examples in section 1.1 
include the summary element.  Suggestion: change the "content" in the 
first (minimal) example to "summary".

- Sam Ruby

---

From: Robert Sayre <[email-masked]>
Date: Wed, 06 Apr 2005 23:09:21 -0400

> first (minimal) example to "summary".

"<summary/>"?

Robert Sayre

---

From: Tim Bray <[email-masked]>
Date: Wed, 06 Apr 2005 20:31:00 -0700

>> first (minimal) example to "summary".

No. --Tim

---

From: Robert Sayre <[email-masked]>
Date: Wed, 06 Apr 2005 23:33:36 -0400

> elements of the extension. I do not recall this being discussed, but 

...?

> reason: not all the schema is presented in fragment form, so the title 

Correct. In 1.2, how about "A complete schema appears in Appendix B."

> reason: demonstrate what extensible indicates upfront.

I am concerned that any extension element in the examples will create a 
procedural issue. I am also concerned that the target audience for a 
prefixed example would be rather small.

> reason: adds no specification value.

Agree.

> Also, if 'resolution' is a term taken from some spec it should be called 

'resolution' is a little sloppy.

How about this:

[[[
Atom allows the use of IRIs [RFC3987], as well as URIs [RFC3986]. IRIs 
can easily be converted to URIs, and every URI is an IRI, so any URI can 
be used where an IRI is needed.. When comparing IRIs serving as atom:id 
values, they MUST NOT be converted to URIs. By definition,
]]]

> to write conversion code differently depending on whether I'm resolving 

Yes, but this is as specified by RFC3987, section 5.1, p4.

> without answers (does 'may' mean 'might' above? defined by who? etc).

Agree.

> reason: state the specification as specification not as a side note.

Agree.

> reason: clearly indicate what conformance prefix binding entails.

Tim covered this.

> reason: give each spec its own bullet point.

Agree.

> have" as we're dealing with plurals.

Agree.

> reason: give each spec its own bullet point.

Agree.

> have" as we're dealing with plurals.

Agree

> reason: prefer operational text; strongly encouraged sounds very like a 

Agree.

>        (text?, anyElement+, (text|anyElement)*))

Agree.

> that thread where we said it was ok.

We shouldn't be at all. We should ditch this reference and the sentence 
that refers to it.

> [RELAX-NC]    OASIS Technical Committee: Committee Specification 21, 
> “RELAX NG Compact Syntax”, November 2002.
> 

ABNF is required to understand the spec, because we refer to rules from 
other specs.

> you require someone to do this, I will do it.

OK

> ** Replace specification keywords in lowercase (argghh!)

OK.

---

From: Eric Scheid <[email-masked]>
Date: Thu, 07 Apr 2005 16:15:54 +1000

>> namespace has been bound previously  to the "xh" prefix in the

tangent: perhaps we could also insert a note along the lines of ...

   "Note: @type="XHTML" does not automatically imbue the contents of
    the atom:content element with the appropriate or necessary XML
    namespace." 

... point being to alert XML ignorant to a possible problem.

Certainly can be better worded.

e.

---

From: Bill de hÓra <[email-masked]>
Date: Thu, 07 Apr 2005 09:19:28 +0100

>> - I believe atomfeed and

I was going to say something about schematron - don't mind it. The spec 
will be clearer for leaving the schematron in.

cheers
Bill

---

From: Sam Ruby <[email-masked]>
Date: Thu, 07 Apr 2005 08:46:43 -0400

>>> first (minimal) example to "summary".

Perhaps it would help if I was more clear.

If you start with this:

   <content>Some text.</content>

And you change content to summary, you end up with this:

   <summary>Some text.</summary>

I happen to be of the opinion that in terms of linear spec space, these 
two examples with be the most cost effective portions of the spec.  Most 
people, after seeing these, will have few questions and will only need 
to take seek out other sections if they have specific questions. 
Coupled with the existance of the feedvalidator, this isn't such a bad 
thing.

I'd like such people to have been exposed to both summary and content 
elements.  Used in a manner that most people would find helpful: i.e., 
non-empty.

- Sam Ruby

---

From: Robert Sayre <[email-masked]>
Date: Thu, 07 Apr 2005 09:13:32 -0400

>   <summary>Some text.</summary>

I've incorporated Sam's suggested wording.

Robert Sayre

---

From: David Powell <[email-masked]>
Date: Thu, 7 Apr 2005 23:15:36 +0100

> elements of the extension. I do not recall this being discussed, but

Yeah, I'm ok with it too. I'm not sure why anyone would want to do it,
but the spirit of Structured Extension elements was that (almost)
anything goes.

-- 
Dave

---

From: Robert Sayre <[email-masked]>
Date: Sun, 10 Apr 2005 16:37:07 -0400

Bill de hÓra wrote:

...
> Drop.
...
> and referred to in 3.3. It's incidental enough to be dropped.

I agree with this one now. The other specs use the older ABNF spec anyway.

> you require someone to do this, I will do it.

I'm having trouble seeing the benefit here. They might work well in the 
HTML version, but I don't think they do in the text version. Could you 
show me an example where it would help the text version?

Robert Sayre

---

From: Bill de hÓra <[email-masked]>
Date: Sun, 10 Apr 2005 22:28:07 +0100

> show me an example where it would help the text version?

I can look at a caption to tell me it's a rnc fragment, without doing a 
double or treble take.

There are captions in the spec anyway, just not 'marked up' as such:

[[[
  3.1.1.2  HTML

    Example atom:title with HTML content:

    ...
    <title type="html">
      Less: &lt;em> &amp;lt; &lt;/em>
    </title>
    ...
]]]

But truth be told, I see no need to justify their inclusion, any more 
than one would need to justify the inclusion of a TOC or page numbers.

cheers
Bill

---

From: Paul Hoffman <[email-masked]>
Date: Sun, 10 Apr 2005 14:34:05 -0700

At 4:37 PM -0400 4/10/05, Robert Sayre wrote:
>>** Figures
>>
>>Please add figure captions for all samples, bnf and rnc fragments. 
>>If you require someone to do this, I will do it.
>
>I'm having trouble seeing the benefit here. They might work well in 
>the HTML version, but I don't think they do in the text version.

I agree with Robert here. If the samples and fragments appear just 
after the paragraph talking about them, I would find the figure names 
more distracting than useful. I didn't trip over anything when 
reading the latest draft.

>Could you show me an example where it would help the text version?

Agree: please point to where they might be useful. A little judicious 
use is fine, but having every fragment labelled would probably be 
overkill.

--Paul Hoffman, Director
--Internet Mail Consortium

---

From: Robert Sayre <[email-masked]>
Date: Sat, 16 Apr 2005 10:57:22 -0400

> but the spirit of Structured Extension elements was that (almost)

Sounds right to me. If I'm not mistaken, we'll need to define 
'anyElement' in the RNC as follows:

anyElement =
    element * {
       (attribute * { text }
        | text
        | anyElement)*
    }

Robert Sayre

---

From: Norman Walsh <[email-masked]>
Date: Mon, 18 Apr 2005 13:34:33 -0400

/ Robert Sayre <[email-masked]> was heard to say:
| David Powell wrote:
|>
|>>- in 6.4; extension schema allow the use of the atom namespace as child
|>>elements of the extension. I do not recall this being discussed, but
|>>personally am +1 to it.
|> Yeah, I'm ok with it too. I'm not sure why anyone would want to do
|> it,
|> but the spirit of Structured Extension elements was that (almost)
|> anything goes.
|
| Sounds right to me. If I'm not mistaken, we'll need to define
| 'anyElement' in the RNC as follows:
|
| anyElement =
|     element * {
|        (attribute * { text }
|         | text
|         | anyElement)*
|     }

It might be a little trickier than that. If you do that, then by

atomInlineOtherContent =
   element atom:content {
      atomCommonAttributes,
      attribute type { atomMediaType }?,
      (text|anyElement)*
   }

it'll be valid to write:

  <atom:content type="application/html+xml">
    <atom:generator>...</atom:generator>

which we probably don't want to allow :-)

The point is that extensions should allow atom:content inside the
extension, is that right?

                                        Be seeing you,
                                          norm

-- 
Norman Walsh <[email-masked]> | Everything should be made as simple as
http://nwalsh.com/            | possible, but no simpler.

---

From: Robert Sayre <[email-masked]>
Date: Mon, 18 Apr 2005 13:42:18 -0400

> extension, is that right?

Yes. Any atom element should be allowed in an extension.

Robert Sayre

---

From: Norman Walsh <[email-masked]>
Date: Mon, 18 Apr 2005 15:57:25 -0400

/ Robert Sayre <[email-masked]> was heard to say:
| Norman Walsh wrote:
|
|> The point is that extensions should allow atom:content inside the
|> extension, is that right?
|
| Yes. Any atom element should be allowed in an extension.

Fix appended.

And I happened to notice that our example feed in 1.1 is invalid.
It does not contain an atom:link element with a relation of
"alternat".

# -*- rnc -*-
# RELAX NG Compact Syntax Grammar for the
# Atom Format Specification Version 07+

namespace atom =
   "http://purl.org/atom/ns#draft-ietf-atompub-format-07"
namespace xhtml = "http://www.w3.org/1999/xhtml"
namespace s = "http://www.ascc.net/xml/schematron"

start = atomFeed | atomEntry

# Common attributes

atomCommonAttributes =
   attribute xml:base { atomUri }?,
   attribute xml:lang { atomLanguageTag }?

# 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:link[@rel='alternate']"
            "An atom:feed must have at least one link element "
            ~ "with a rel attribute of 'alternate'."
         ]
      ]
      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*
       & atomCopyright?
       & atomGenerator?
       & atomIcon?
       & atomId?
       & atomImage?
       & atomLink+
       & atomSubtitle?
       & atomTitle
       & atomUpdated
       & extensionElement*),
      atomEntry*
   }

# atom:entry

atomEntry =
   [
      s:rule [
         context = "atom:entry"
         s:assert [
            test = "atom:link[@rel='alternate'] or atom:content"
            "An atom:entry must have at least one link element "
            ~ "with a rel attribute of 'alternate' or 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."
         ]
      ]

      # N.B. This rule doesn't test for content with a non-binary type.
      s:rule [
         context = "atom:entry"
         s:assert [
            test = "atom:summary or atom:content[not(@src)]"
            "An atom:entry must have an atom:summary "
            ~ "if the atom:content element is empty."
         ]
      ]
   ]
   element atom:entry {
      atomCommonAttributes,
      (atomAuthor?
       & atomCategory*
       & atomContent?
       & atomContributor*
       & atomCopyright?
       & atomId
       & atomLink*
       & atomPublished?
       & 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|anyForeignElement)*
   }

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 }?,
      empty
   }

# atom:contributor

atomContributor = element atom:contributor { atomPersonConstruct }

# atom:copyright

atomCopyright = element atom:copyright { atomTextConstruct }

# atom:generator

atomGenerator = element atom:generator {
   atomCommonAttributes,
   attribute url { atomUri }?,
   attribute version { text }?,
   text
}

# atom:icon

atomIcon = element atom:icon {
   atomCommonAttributes,
   (atomUri)
}

# atom:id

atomId = element atom:id {
   atomCommonAttributes,
   (atomUri)
}

# atom:image

atomImage = element atom:image {
   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 }?,
      empty
   }

# atom:published

atomPublished = element atom:published { atomDateConstruct }

# atom:source

atomSource =
   element atom:source {
      atomCommonAttributes,
      (atomAuthor?
       & atomCategory*
       & atomContributor*
       & atomCopyright?
       & atomGenerator?
       & atomIcon?
       & atomId?
       & atomImage?
       & atomLink+
       & 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 = ".+@.+" }

# Extensibility

simpleExtensionElement =
   element * - atom:* {
      text
   }

structuredExtensionElement =
   element * - atom:* {
      (attribute * { text }+,
         (text|anyElement)*)
    | (attribute * { text }*,
       (text?, anyElement+, (text|anyElement)*))
   }

extensionElement =
   simpleExtensionElement | structuredExtensionElement

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

                                        Be seeing you,
                                          norm

---

From: Robert Sayre <[email-masked]>
Date: Mon, 18 Apr 2005 16:02:21 -0400

> | Yes. Any atom element should be allowed in an extension.

Thank you.

> It does not contain an atom:link element with a relation of

It's valid, because link elements without the rel attribute have a 
relation of "alternate".[0]

Robert Sayre

[0] 
<http://atompub.org/2005/04/04/draft-ietf-atompub-format-07.html#rfc.section.4.2.9.2>

---

From: Norman Walsh <[email-masked]>
Date: Mon, 18 Apr 2005 16:53:36 -0400

/ Robert Sayre <[email-masked]> was heard to say:
| It's valid, because link elements without the rel attribute have a
| relation of "alternate".[0]

Oops. Then my Schematron is wrong. Fixed and formatted for 72 cols.

                                        Be seeing you,
                                          norm

-- 
Norman Walsh <[email-masked]> | Thanks to words, we have been able to
http://nwalsh.com/            | rise above the brutes; and thanks to
                              | words, we have often sunk to the level
                              | of the demons.--Aldous Huxley