RFC 4287

The Atom Syndication Format

๐Ÿ“… published December 2005, from ietf

Request for Comments 4287: The Atom Syndication Format ๐Ÿ“ฐโœจ

Okay bestie, here's the header info first. The document is by M. Nottingham, Ed. and R. Sayre, Ed. and it's from the Network Working Group ๐Ÿงš. It's a Standards Track doc, dated December 2005. The header doesn't list anything it obsoletes or updates, so there's nothing to chase down there ๐ŸŒธ.


Status of This Memo ๐Ÿ“‹

This doc specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements ๐Ÿ’ฌ. If you want the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐Ÿ”. Distribution of this memo is unlimited ๐Ÿฆ‹.


The copyright line reads: "Copyright (C) The Internet Society (2005)." ๐Ÿ’œ


Abstract ๐ŸŒˆ

This doc defines Atom, an XML-based format for syndicating Web content and metadata ๐Ÿ“ก. Basically it's how sites share their updates in a structured way ๐Ÿ’–.


Table of Contents ๐Ÿ“š

   1. Introduction ....................................................3
      1.1. Examples ...................................................3
      1.2. Namespace and Version ......................................5
      1.3. Notational Conventions .....................................5
   2. Atom Documents ..................................................6
   3. Common Atom Constructs ..........................................7
      3.1. Text Constructs ............................................7
           3.1.1. The "type" Attribute ................................8
      3.2. Person Constructs .........................................10
           3.2.1. The "atom:name" Element ............................10
           3.2.2. The "atom:uri" Element .............................10
           3.2.3. The "atom:email" Element ...........................10
      3.3. Date Constructs ...........................................10
   4. Atom Element Definitions .......................................11
      4.1. Container Elements ........................................11
           4.1.1. The "atom:feed" Element ............................11
           4.1.2. The "atom:entry" Element ...........................13
           4.1.3. The "atom:content" Element .........................14
      4.2. Metadata Elements .........................................17
           4.2.1. The "atom:author" Element ..........................17
           4.2.2. The "atom:category" Element ........................18
           4.2.3. The "atom:contributor" Element .....................18
           4.2.4. The "atom:generator" Element .......................18
           4.2.5. The "atom:icon" Element ............................19
           4.2.6. The "atom:id" Element ..............................19
           4.2.7. The "atom:link" Element ............................21
           4.2.8. The "atom:logo" Element ............................23
           4.2.9. The "atom:published" Element .......................23
           4.2.10. The "atom:rights" Element .........................24
           4.2.11. The "atom:source" Element .........................24
           4.2.12. The "atom:subtitle" Element .......................25
           4.2.13. The "atom:summary" Element ........................25
           4.2.14. The "atom:title" Element ..........................25
           4.2.15. The "atom:updated" Element ........................25
   5. Securing Atom Documents ........................................26
      5.1. Digital Signatures ........................................26
      5.2. Encryption ................................................27
      5.3. Signing and Encrypting ....................................28
   6. Extending Atom .................................................28
      6.1. Extensions from Non-Atom Vocabularies .....................28
      6.2. Extensions to the Atom Vocabulary .........................28
      6.3. Processing Foreign Markup .................................28
      6.4. Extension Elements ........................................29
           6.4.1. Simple Extension Elements ..........................29
           6.4.2. Structured Extension Elements ......................29
   7. IANA Considerations ............................................30
      7.1. Registry of Link Relations ................................31
   8. Security Considerations ........................................31
      8.1. HTML and XHTML Content ....................................31
      8.2. URIs ......................................................31
      8.3. IRIs ......................................................31
      8.4. Spoofing ..................................................31
      8.5. Encryption and Signing ....................................32
   9. References .....................................................32
      9.1. Normative References ......................................32
      9.2. Informative References ....................................34
   Appendix A. Contributors ..........................................35
   Appendix B. RELAX NG Compact Schema ...............................35

1. Introduction โœจ

Atom is an XML-based document format for lists of related info called "feeds" ๐Ÿ“ƒ. Each feed is made of items called "entries", and every entry can carry its own extensible set of attached metadata ๐ŸŽ€. For example, every entry has a title ๐Ÿ’….

The main thing Atom is built for is syndicating Web content, like weblogs and news headlines, out to Web sites and straight to user agents ๐ŸŒ๐Ÿ”ฅ.

1.1. Examples ๐Ÿง

Here's a brief feed with one entry:

   <?xml version="1.0" encoding="utf-8"?>
   <feed xmlns="http://www.w3.org/2005/Atom">

     <title>Example Feed</title>
     <link href="http://example.org/"/>
     <updated>2003-12-13T18:30:02Z</updated>
     <author>
       <name>John Doe</name>
     </author>
     <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>

     <entry>
       <title>Atom-Powered Robots Run Amok</title>
       <link href="http://example.org/2003/12/13/atom03"/>
       <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
       <updated>2003-12-13T18:30:02Z</updated>
       <summary>Some text.</summary>
     </entry>

   </feed>

And here's a more extensive one, also with a single entry ๐Ÿฆ‹:

   <?xml version="1.0" encoding="utf-8"?>
   <feed xmlns="http://www.w3.org/2005/Atom">
     <title type="text">dive into mark</title>
     <subtitle type="html">
       A &lt;em&gt;lot&lt;/em&gt; of effort
       went into making this effortless
     </subtitle>
     <updated>2005-07-31T12:29:29Z</updated>
     <id>tag:example.org,2003:3</id>
     <link rel="alternate" type="text/html"
      hreflang="en" href="http://example.org/"/>
     <link rel="self" type="application/atom+xml"
      href="http://example.org/feed.atom"/>
     <rights>Copyright (c) 2003, Mark Pilgrim</rights>
     <generator uri="http://www.example.com/" version="1.0">
       Example Toolkit
     </generator>
     <entry>
       <title>Atom draft-07 snapshot</title>
       <link rel="alternate" type="text/html"
        href="http://example.org/2005/04/02/atom"/>
       <link rel="enclosure" type="audio/mpeg" length="1337"
        href="http://example.org/audio/ph34r_my_podcast.mp3"/>
       <id>tag:example.org,2003:3.2397</id>
       <updated>2005-07-31T12:29:29Z</updated>
       <published>2003-12-13T08:29:29-04:00</published>
       <author>
         <name>Mark Pilgrim</name>
         <uri>http://example.org/</uri>
         <email>f8dy@example.com</email>
       </author>
       <contributor>
         <name>Sam Ruby</name>
       </contributor>
       <contributor>
         <name>Joe Gregorio</name>
       </contributor>
       <content type="xhtml" xml:lang="en"
        xml:base="http://diveintomark.org/">
         <div xmlns="http://www.w3.org/1999/xhtml">
           <p><i>[Update: The Atom draft is finished.]</i></p>
         </div>
       </content>
     </entry>
   </feed>

1.2. Namespace and Version ๐Ÿท๏ธ

The XML Namespaces URI [W3C.REC-xml-names-19990114] for the XML data format in this spec is:

http://www.w3.org/2005/Atom

For convenience, you can call this data format "Atom 1.0" ๐Ÿ’–. Inside the spec, it's just "Atom" ๐Ÿซถ.

1.3. Notational Conventions ๐Ÿ“

This spec describes conformance using two artifacts: Atom Feed Documents and Atom Entry Documents ๐Ÿ“„. It also puts some requirements on Atom Processors ๐Ÿ› ๏ธ.

The spec uses the namespace prefix "atom:" for the Namespace URI from Section 1.2, above. The prefix is arbitrary and has no semantic significance, so you're free to pick a different one if you want ๐Ÿงš.

Atom is specified using terms from the XML Infoset [W3C.REC-xml-infoset-20040204]. There's a shorthand for two common terms, though. The phrase "Information Item" gets dropped when naming Element Information Items and Attribute Information Items. So when the spec says "element," it means an Element Information Item, and when it says "attribute," it means an Attribute Information Item ๐ŸŽ€.

Some sections are illustrated with fragments of a non-normative RELAX NG Compact schema [RELAX-NG]. The text of the spec is what defines conformance, though. A complete schema is in Appendix B ๐Ÿ’œ.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, [RFC2119], as scoped to those conformance targets ๐Ÿ”‘.

2. Atom Documents โœจ

okay so this spec covers two kinds of Atom Documents ๐Ÿฆ‹: Atom Feed Documents and Atom Entry Documents.

An Atom Feed Document is a representation of an Atom feed. It has the feed's metadata plus some or all of the entries that belong to it, and its root is atom:feed. ๐Ÿ’–

An Atom Entry Document represents exactly one Atom entry, on its own and not inside a feed. Its root is atom:entry. ๐ŸŒธ

namespace atom = "http://www.w3.org/2005/Atom"
start = atomFeed | atomEntry

Both kinds are described in terms of the XML Information Set, serialized as XML 1.0 [W3C.REC-xml-20040204], and they use the "application/atom+xml" media type. โœจ Atom Documents MUST be well-formed XML. This spec doesn't define a DTD for them, so it doesn't require them to be valid in the XML sense. ๐ŸŽ€

Atom is happy to use IRIs [RFC3987]. Every URI [RFC3986] is also an IRI, so you can drop a URI anywhere this doc says IRI. There are two special cases though ๐Ÿ‘€. First, when an IRI that isn't also a URI gets used for dereferencing, it MUST be mapped to a URI using the steps in Section 3.1 of [RFC3987]. Second, when an IRI is acting as an atom:id value, it MUST NOT be mapped, so the comparison can work the way Section 4.2.6.1 describes. ๐Ÿ’…

Any element defined here MAY have an xml:base attribute [W3C.REC-xmlbase-20010627]. When xml:base shows up in an Atom Document, it does the job described in section 5.1.1 of [RFC3986]. It sets the base URI (or IRI) for resolving any relative references inside the attribute's effective scope. ๐Ÿฆ‹

Any element defined here MAY also have an xml:lang attribute. Its content says what natural language the element and its descendants are in. The language context only matters for elements and attributes this spec marks as "Language-Sensitive" ๐ŸŒˆ. The rules for xml:lang content and interpretation live in XML 1.0 [W3C.REC-xml-20040204], Section 2.12.

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

Atom is extensible! ๐Ÿงš Section 6 of this document has the full rundown on how Atom Documents can be extended.

Atom Processors MAY keep state sourced from Atom Feed Documents and combine them with other Atom Feed Documents, so they can build a contiguous view of a feed. ๐Ÿซถ How you actually stitch feed documents together to rebuild a feed (updating entries and metadata, handling missing entries, and so on) is out of this spec's scope, so that's on you, bestie. ๐Ÿ˜…


3. Common Atom Constructs ๐Ÿ’œ

Lots of Atom's elements share the same few structures. This section defines those shared structures and their requirements so the element definitions can just point back here. ๐Ÿ“

When an element is identified as a particular kind of construct, it inherits that construct's requirements from this section. โœจ

Heads up: there MUST NOT be any white space in a Date construct or in any IRI. Some XML-emitting implementations insert white space around values by default, and those implementations will emit invalid Atom Documents. ๐Ÿ˜ญ Not okay!

3.1. Text Constructs

A Text construct holds human-readable text, usually in small amounts. Its content is Language-Sensitive. ๐Ÿ’–

atomPlainTextConstruct =
   atomCommonAttributes,
   attribute type { "text" | "html" }?,
   text

atomXHTMLTextConstruct =
   atomCommonAttributes,
   attribute type { "xhtml" },
   xhtmlDiv

atomTextConstruct = atomPlainTextConstruct | atomXHTMLTextConstruct

3.1.1. The "type" Attribute

Text constructs MAY have a "type" attribute. If it's there, the value MUST be one of "text", "html", or "xhtml". If the "type" attribute isn't provided, Atom Processors MUST behave as though it were present with the value "text". ๐ŸŽ€ Unlike the atom:content element from Section 4.1.3, MIME media types [MIMEREG] MUST NOT be used as values for "type" on Text constructs. Keep it simple, babe! ๐Ÿ’…

3.1.1.1. Text

Here's an example atom:title with text content:

...
<title type="text">
  Less: &lt;
</title>
...

If the value is "text", the Text construct's content MUST NOT contain child elements. This text is meant to be read by humans, so Atom Processors MAY collapse white space (line breaks included) and display it with typographic stuff like justification and proportional fonts. โœจ

3.1.1.2. HTML

Here's an example atom:title with HTML content:

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

If "type" is "html", the Text construct's content MUST NOT contain child elements and SHOULD be suitable for handling as HTML [HTML]. Any markup inside MUST be escaped, for example "<br>" as "&lt;br>". ๐Ÿฆ‹ The HTML markup inside SHOULD be the kind that could validly sit directly inside an HTML <DIV> element after unescaping. Atom Processors that display this content MAY use that markup to help with the display. ๐ŸŒธ

3.1.1.3. XHTML

Here's an example atom:title with XHTML content:

...
<title type="xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <xhtml:div>
    Less: <xhtml:em> &lt; </xhtml:em>
  </xhtml:div>
</title>
...

If "type" is "xhtml", the Text construct's content MUST be a single XHTML div element [XHTML] and SHOULD be suitable for handling as XHTML. The XHTML div element itself MUST NOT be considered part of the content. ๐Ÿง Atom Processors that display the content MAY use the markup to help display it. Escaped characters like "&" and ">" stand for those characters, not for markup. ๐Ÿ’€

Here are some examples of valid XHTML content:

...
<summary type="xhtml">
   <div xmlns="http://www.w3.org/1999/xhtml">
      This is <b>XHTML</b> content.
   </div>
</summary>
...
<summary type="xhtml">
   <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">
      This is <xhtml:b>XHTML</xhtml:b> content.
   </xhtml:div>
</summary>
...

This next one assumes the XHTML namespace has already been bound to the "xh" prefix earlier in the document. ๐ŸŒˆ

...
<summary type="xhtml">
   <xh:div>
      This is <xh:b>XHTML</xh:b> content.
   </xh:div>
</summary>
...

3.2. Person Constructs

A Person construct is an element describing a person, a corporation, or something similar (from here on, just "person"). ๐Ÿงš

atomPersonConstruct =
   atomCommonAttributes,
   (element atom:name { text }
    & element atom:uri { atomUri }?
    & element atom:email { atomEmailAddress }?
    & extensionElement*)

This spec doesn't care what order the child elements show up in a Person construct. Person constructs can also carry extension Metadata elements (see Section 6.4). ๐Ÿ’…

3.2.1. The "atom:name" Element

The "atom:name" element's content is a human-readable name for the person, and it's Language-Sensitive. Person constructs MUST contain exactly one "atom:name" element. ๐ŸŽ€

3.2.2. The "atom:uri" Element

The "atom:uri" element's content is an IRI associated with the person. Person constructs MAY contain an atom:uri element, but they MUST NOT contain more than one. The content of atom:uri in a Person construct MUST be an IRI reference [RFC3987]. ๐Ÿฆ‹

3.2.3. The "atom:email" Element

The "atom:email" element's content is an e-mail address associated with the person. Person constructs MAY contain an atom:email element, but they MUST NOT contain more than one. Its content MUST conform to the "addr-spec" production in [RFC2822]. ๐Ÿ’Œ

3.3. Date Constructs

A Date construct is an element whose content MUST conform to the "date-time" production in [RFC3339]. On top of that, an uppercase "T" MUST be used to separate the date and time, and an uppercase "Z" MUST be present when there's no numeric time zone offset. ๐Ÿ•

atomDateConstruct =
   atomCommonAttributes,
   xsd:dateTime

These date values happen to be compatible with [ISO.8601.1988], [W3C.NOTE-datetime-19980827], and [W3C.REC-xmlschema-2-20041028]. ๐ŸŒธ Here are some example Date constructs:

<updated>2003-12-13T18:30:02Z</updated>
<updated>2003-12-13T18:30:02.25Z</updated>
<updated>2003-12-13T18:30:02+01:00</updated>
<updated>2003-12-13T18:30:02.25+01:00</updated>

Date values SHOULD be as accurate as possible. For example, it would generally be inappropriate for a publishing system to stamp the same timestamp on several entries that were published over the course of a single day. ๐Ÿ˜ญ Give your entries their own real times, please!


4. Atom Element Definitions ๐ŸŒŸ

4.1. Container Elements ๐Ÿ‘‘

4.1.1. The "atom:feed" Element ๐ŸŽ€

okay so atom:feed is the main document element of an Atom Feed Document, basically the container that holds all the feed's metadata and data ๐Ÿ’– its element children are metadata elements first, then zero or more atom:entry children after them.

atomFeed =
   element atom:feed {
      atomCommonAttributes,
      (atomAuthor*
       & atomCategory*
       & atomContributor*
       & atomGenerator?
       & atomIcon?
       & atomId
       & atomLink*
       & atomLogo?
       & atomRights?
       & atomSubtitle?
       & atomTitle
       & atomUpdated
       & extensionElement*),
      atomEntry*
   }

this spec doesn't care about the order of atom:entry elements inside the feed ๐Ÿคทโ€โ™€๏ธ no ranking, no vibes check, just vibes.

Some child elements are defined by this spec, and some of them are required (not all of them, so read carefully ๐Ÿ‘€):

  • atom:feed elements MUST contain one or more atom:author elements, unless all of the feed's child atom:entry elements contain at least one atom:author element.
  • atom:feed elements MAY contain any number of atom:category elements.
  • atom:feed elements MAY contain any number of atom:contributor elements.
  • atom:feed elements MUST NOT contain more than one atom:generator element.
  • atom:feed elements MUST NOT contain more than one atom:icon element.
  • atom:feed elements MUST NOT contain more than one atom:logo element.
  • atom:feed elements MUST contain exactly one atom:id element.
  • atom:feed elements SHOULD contain one atom:link element with a rel attribute value of "self". This is the preferred URI for retrieving Atom Feed Documents representing this Atom feed ๐ŸŒธ
  • atom:feed 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:feed elements MAY contain additional atom:link elements beyond those described above.
  • atom:feed elements MUST NOT contain more than one atom:rights element.
  • atom:feed elements MUST NOT contain more than one atom:subtitle element.
  • atom:feed elements MUST contain exactly one atom:title element.
  • atom:feed elements MUST contain exactly one atom:updated element.

ngl this is the part where people mess up the most, so pls double check your feed ๐Ÿ˜ญ

Here's the duplicate situation: if you've got multiple atom:entry elements with the same atom:id value in one Atom Feed Document, they all count as the same entry ๐Ÿฆ‹ their atom:updated timestamps SHOULD be different, though. If the same ID shows up more than once, Atom Processors MAY decide to show all of them, or just some of them. One typical move is showing only the one with the latest atom:updated timestamp, which is honestly iconic behaviour โœจ

4.1.1.1. Providing Textual Content ๐Ÿ“

Experience has taught us that feeds with textual content are, generally speaking, way more useful than feeds without it ๐Ÿ’… some apps (full-text indexers are the main example) need a minimum amount of text or (X)HTML to work reliably and predictably. Feed producers should keep this in mind.

It's advisable that each atom:entry element has a non-empty atom:title element, a non-empty atom:content element when that element is present, and a non-empty atom:summary element when the entry has no atom:content element. BUT, the absence of atom:summary is not an error, and Atom Processors MUST NOT fail to function correctly because of that absence. So no panic if it's missing ๐Ÿซถ

Wait, I need to say that properly: the requirement there is that Atom Processors MUST NOT fail to function correctly as a consequence of such an absence. Processors MUST NOT break just because atom:summary is missing ๐Ÿ’€

4.1.2. The "atom:entry" Element ๐Ÿงš

The atom:entry element represents one individual entry, and it acts as a container for that entry's metadata and data ๐Ÿ’œ it can show up as a child of atom:feed, or it can be the top-level element of a stand-alone Atom Entry Document, so it's very flexible.

atomEntry =
   element atom:entry {
      atomCommonAttributes,
      (atomAuthor*
       & atomCategory*
       & atomContent?
       & atomContributor*
       & atomId
       & atomLink*
       & atomPublished?
       & atomRights?
       & atomSource?
       & atomSummary?
       & atomTitle
       & atomUpdated
       & extensionElement*)
   }

Once again, this spec doesn't care about the order that the child elements show up in atom:entry ๐Ÿคทโ€โ™€๏ธ and it does require some of them to be present, so check the list:

  • atom:entry elements MUST contain one or more atom:author elements, unless the atom:entry contains an atom:source element that contains an atom:author element or, in an Atom Feed Document, the atom:feed element contains an atom:author element itself.
  • atom:entry elements MAY contain any number of atom:category elements.
  • atom:entry elements MUST NOT contain more than one atom:content element.
  • atom:entry elements MAY contain any number of atom:contributor elements.
  • atom:entry elements MUST contain exactly one atom:id element.
  • 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.
  • atom:entry elements MUST NOT contain more than one atom:published element.
  • atom:entry elements MUST NOT contain more than one atom:rights element.
  • atom:entry elements MUST NOT contain more than one atom:source element.
  • atom:entry elements MUST contain an atom:summary element in either of the following cases:
    • the atom:entry contains an atom:content that has a "src" attribute (and is thus empty).
    • the atom:entry contains content that is encoded in Base64; i.e., the "type" attribute of atom:content is a MIME media type [MIMEREG], but is not an XML media type [RFC3023], does not begin with "text/", and does not end with "/xml" or "+xml".
  • atom:entry elements MUST NOT contain more than one atom:summary element.
  • atom:entry elements MUST contain exactly one atom:title element.
  • atom:entry elements MUST contain exactly one atom:updated element.

4.1.3. The "atom:content" Element ๐Ÿ’–

The atom:content element either contains the content of the entry or links to it ๐ŸŽ€ and the content of atom:content is Language-Sensitive, so the language really matters here ๐ŸŒˆ

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

4.1.3.1. The "type" Attribute ๐Ÿฆ‹

On atom:content, the type attribute's value MAY be one of "text", "html", or "xhtml". If it isn't one of those, it MUST conform to the syntax of a MIME media type, but it MUST NOT be a composite type (see Section 4.2.6 of [MIMEREG]). And if neither the type attribute nor the src attribute is provided, Atom Processors MUST behave as though the type attribute were present with a value of "text" ๐Ÿ’…

4.1.3.2. The "src" Attribute ๐ŸŒธ

atom:content MAY have a src attribute, and its value MUST be an IRI reference [RFC3987]. If src is present, atom:content MUST be empty. Atom Processors MAY use the IRI to retrieve the content, and they MAY choose to ignore remote content or to present it differently from local content ๐Ÿ‘€

If src is present, the type attribute SHOULD be provided, and it MUST be a MIME media type [MIMEREG], not "text", "html", or "xhtml". The value is advisory, meaning that when the matching URI (mapped from an IRI, if needed) is dereferenced, if the server providing that content also gives a media type, the server's media type is the authoritative one ๐Ÿงš

4.1.3.3. Processing Model ๐Ÿ”ฅ

Atom Documents MUST conform to the following rules. Atom Processors MUST interpret atom:content according to the first applicable rule, so order matters here, bestie โœจ

  1. If the value of type is "text", the content of atom:content MUST NOT contain child elements. This text is meant to be read by humans, so Atom Processors MAY collapse white space (including line breaks), and display the text with typographic techniques like justification and proportional fonts ๐Ÿ“
  2. If the value of type is "html", the content of atom:content MUST NOT contain child elements, and SHOULD be suitable for handling as HTML [HTML]. The HTML markup MUST be escaped; for example, "<br>" as "&lt;br>". The HTML markup SHOULD be such that it could validly appear directly within an HTML <DIV> element. Atom Processors that display the content MAY use the markup to help display it ๐Ÿ’–
  3. If the value of type is "xhtml", the content of atom:content MUST be a single XHTML div element [XHTML], and SHOULD be suitable for handling as XHTML. The XHTML div element itself MUST NOT be considered part of the content. Atom Processors that display the content MAY use the markup to help display it. Escaped versions of characters such as "&" and ">" represent those characters, not markup ๐ŸŒˆ
  4. If the value of type is an XML media type [RFC3023], or ends with "+xml" or "/xml" (case insensitive), the content of atom:content MAY include child elements and SHOULD be suitable for handling as the indicated media type. If the src attribute is not provided, this would normally mean that the atom:content element contains a single child element that serves as the root element of the XML document of the indicated type ๐Ÿซถ
  5. If the value of type begins with "text/" (case insensitive), the content of atom:content MUST NOT contain child elements ๐Ÿ™ˆ
  6. For all other values of type, the content of atom:content MUST be a valid Base64 encoding, as described in [RFC3548], section 3. When decoded, it SHOULD be suitable for handling as the indicated media type. In this case, the characters in the Base64 encoding MAY be preceded and followed in the atom:content element by white space, and lines are separated by a single newline (U+000A) character ๐Ÿฆ‹

4.1.3.4. Examples โœจ

okay so here's the XHTML inline vibe ๐Ÿ’… you put a <div> in the xmlns namespace and then bold stuff with <b>, and it's giving clean content ๐ŸŽ€

...
<content type="xhtml">
   <div xmlns="http://www.w3.org/1999/xhtml">
      This is <b>XHTML</b> content.
   </div>
</content>
...
<content type="xhtml">
   <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml">
      This is <xhtml:b>XHTML</xhtml:b> content.
   </xhtml:div>
</content>
...

and if the XHTML namespace is already bound to the "xh" prefix earlier in the document, you can skip the namespace declaration and just write it like this ๐Ÿฆ‹

...
<content type="xhtml">
   <xh:div>
      This is <xh:b>XHTML</xh:b> content.
   </xh:div>
</content>
...

4.2. Metadata Elements ๐ŸŒธ

4.2.1. The "atom:author" Element ๐Ÿ’–

the atom:author element is a Person construct that tells you who wrote the entry or feed. the main character of the authorship ๐Ÿ‘‘

atomAuthor = element atom:author { atomPersonConstruct }

so if an atom:entry doesn't have any atom:author elements, the atom:author elements inside its atom:source element are the ones that count ๐Ÿงš and in an Atom Feed Document, if there are no atom:author elements in those spots either, then the atom:author elements of the containing atom:feed element get applied to the entry instead. it's like a whole inheritance arc ๐Ÿ˜ญ

4.2.2. The "atom:category" Element ๐Ÿท๏ธ

the atom:category element is all about a category attached to an entry or feed. this spec doesn't assign any meaning to whatever content (if any) sits inside it, so don't look for a deep vibe there ๐Ÿ™ˆ

atomCategory =
   element atom:category {
      atomCommonAttributes,
      attribute term { text },
      attribute scheme { atomUri }?,
      attribute label { text }?,
      undefinedContent
   }

4.2.2.1. The "term" Attribute ๐Ÿ“

the term attribute is a string that names the category the entry or feed belongs to. category elements MUST have a "term" attribute. no exceptions, bestie ๐Ÿ’…

4.2.2.2. The "scheme" Attribute ๐ŸŒˆ

the scheme attribute is an IRI that identifies a categorization scheme. category elements MAY have a "scheme" attribute, so it's optional but very cute when it's there โœจ

4.2.2.3. The "label" Attribute ๐ŸŽ€

the label attribute gives a human-readable label for display in end-user apps. its content is Language-Sensitive, so the language matters here ๐ŸŒ also, entities like "&amp;" and "&lt;" stand for their characters ("&" and "<", respectively), NOT markup. category elements MAY have a "label" attribute too ๐Ÿ’œ

4.2.3. The "atom:contributor" Element ๐Ÿซถ

the atom:contributor element is a Person construct for a person or other entity who contributed to the entry or feed. the helpers, the glue, the real ones ๐Ÿงš

atomContributor = element atom:contributor { atomPersonConstruct }

4.2.4. The "atom:generator" Element ๐Ÿค–

the atom:generator element's content names the agent that generated a feed. it's there for debugging and other purposes, so it's basically the feed's "made by" tag ๐Ÿ”ฅ

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

when this element is present, its content MUST be a string that's a human-readable name for the generating agent. again, "&amp;" and "&lt;" stand for "&" and "<" respectively, not markup ๐Ÿ’…

the atom:generator element MAY have a "uri" attribute, and its value MUST be an IRI reference [RFC3987]. when you dereference it, the resulting URI (mapped from an IRI, if needed) SHOULD produce a representation that's relevant to that agent ๐Ÿฆ‹

and the atom:generator element MAY have a "version" attribute that tells you the version of the generating agent. version numbers, iykyk ๐ŸŒธ

4.2.5. The "atom:icon" Element ๐Ÿ–ผ๏ธ

the atom:icon element's content is an IRI reference [RFC3987] pointing at an image that gives a feed its iconic look ๐Ÿ‘‘

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

the image SHOULD have an aspect ratio of one (horizontal) to one (vertical), and it SHOULD be suitable for presenting at a small size. small but mighty โœจ

4.2.6. The "atom:id" Element ๐Ÿ†”

the atom:id element is a permanent, universally unique identifier for an entry or feed. this is the forever name, the main character ID ๐Ÿ’–

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

its content MUST be an IRI, as defined by [RFC3987]. note that the definition of "IRI" excludes relative references ๐Ÿ™… and even if the IRI uses a scheme you could dereference, Atom Processors MUST NOT assume it can be dereferenced. don't go poking at it, it's giving unsafe ๐Ÿ˜ญ

when an Atom Document gets relocated, migrated, syndicated, republished, exported, or imported, the content of its atom:id element MUST NOT change. put another way, an atom:id element belongs to every instantiation of a particular Atom entry or feed, so revisions keep the same atom:id content. it's suggested that you store the atom:id element along with the resource it belongs to ๐Ÿซถ

the content of an atom:id element MUST be created in a way that assures uniqueness. no copycats allowed ๐Ÿ”ฅ

because IRIs that would be equivalent once mapped to URIs and dereferenced can still get confused with each other, the following normalization strategy SHOULD be applied when generating atom:id elements ๐Ÿงผ

  • Provide the scheme in lowercase characters.
  • Provide the host, if any, in lowercase characters.
  • Only perform percent-encoding where it is essential.
  • Use uppercase A through F characters when percent-encoding.
  • Prevent dot-segments from appearing in paths.
  • For schemes that define a default authority, use an empty authority if the default is desired.
  • For schemes that define an empty path to be equivalent to a path of "/", use "/".
  • For schemes that define a port, use an empty port if the default is desired.
  • Preserve empty fragment identifiers and queries.
  • Ensure that all components of the IRI are appropriately character normalized, e.g., by using NFC or NFKC.

4.2.6.1. Comparing atom:id ๐Ÿ”

instances of atom:id elements can be compared to figure out whether an entry or feed is one you've seen before. processors MUST compare atom:id elements on a character-by-character basis (case-sensitive, no vibes-based matching). comparison operations MUST be based solely on the IRI character strings and MUST NOT rely on dereferencing the IRIs or URIs mapped from them ๐Ÿ™…โ€โ™€๏ธ

so two IRIs that resolve to the same resource but aren't character-for-character identical count as different for identifier comparison. not the same bestie, sorry ๐Ÿ’€

for example, these are four distinct identifiers, even though they only differ in case ๐ŸŽ€

http://www.example.org/thing
http://www.example.org/Thing
http://www.EXAMPLE.org/thing
HTTP://www.example.org/thing

and these are three distinct identifiers too, because IRI %-escaping counts for comparison purposes ๐Ÿฆ‹

http://www.example.com/~bob
http://www.example.com/%7ebob
http://www.example.com/%7Ebob

the atom:link element defines a reference from an entry or feed to a Web resource. this spec doesn't assign any meaning to its content (if any), so the link is the whole point โœจ

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
   }

4.2.7.1. The "href" Attribute ๐ŸŒ

the href attribute holds the link's IRI. atom:link elements MUST have an href attribute, and its value MUST be a IRI reference [RFC3987]. no href, no link, periodt ๐Ÿ’…

4.2.7.2. The "rel" Attribute ๐Ÿ’ซ

atom:link elements MAY have a "rel" attribute that tells you the link relation type. if the "rel" attribute isn't there, the link element MUST be interpreted as if the link relation type is "alternate" ๐Ÿชž

the value of "rel" MUST be a string that's non-empty and matches either the "isegment-nz-nc" or the "IRI" production in [RFC3987]. note that a relative reference other than a simple name is not allowed, so don't try it ๐Ÿ™ˆ if a name is given, implementations MUST consider the link relation type equivalent to that same name registered in the IANA Registry of Link Relations (Section 7). that means it's the same as the IRI you'd get by adding the value of the rel attribute onto the string "http://www.iana.org/assignments/relation/" ๐Ÿงš the value of "rel" describes what the link means, but it doesn't impose any behavioral requirements on Atom Processors. it's the vibe check, not a rulebook ๐Ÿ’œ

this document defines five initial values for the Registry of Link Relations ๐Ÿ“

  1. The value "alternate" signifies that the IRI in the value of the href attribute identifies an alternate version of the resource described by the containing element.
  2. The value "related" signifies that the IRI in the value of the href attribute identifies a resource related to the resource described by the containing element. for example, the feed for a site that discusses the performance of the search engine at "http://search.example.com" might contain, as a child of atom:feed:
<link rel="related" href="http://search.example.com/"/>

an identical link might appear as a child of any atom:entry whose content contains a discussion of that same search engine ๐Ÿ‘€

  1. The value "self" signifies that the IRI in the value of the href attribute identifies a resource equivalent to the containing element ๐Ÿชž
  2. The value "enclosure" signifies that the IRI in the value of the href attribute identifies a related resource that is potentially large in size and might require special handling. for atom:link elements with rel="enclosure", the length attribute SHOULD be provided ๐Ÿ“ฆ
  3. The value "via" signifies that the IRI in the value of the href attribute identifies a resource that is the source of the information provided in the containing element ๐ŸŒŸ

4.2.7.3. The "type" Attribute ๐ŸŽ€

on the link element, the "type" attribute's value is an advisory media type. it's a hint about the type of the representation expected back when the href attribute gets dereferenced. the type attribute does NOT override the actual media type returned with the representation, so trust the server ๐Ÿ’… link elements MAY have a type attribute, and its value MUST conform to the syntax of a MIME media type [MIMEREG].

4.2.7.4. The "hreflang" Attribute ๐ŸŒ

the "hreflang" attribute's content describes the language of the resource pointed to by the href attribute. when it's used together with rel="alternate", it implies a translated version of the entry, so it's basically the translation glow-up ๐Ÿฆ‹ link elements MAY have an hreflang attribute, and its value MUST be a language tag [RFC3066].

4.2.7.5. The "title" Attribute ๐Ÿ“

the "title" attribute conveys human-readable info about the link. its content is Language-Sensitive, and entities like "&amp;" and "&lt;" represent their characters ("&" and "<", respectively), not markup ๐Ÿง link elements MAY have a title attribute.

4.2.7.6. The "length" Attribute ๐Ÿ“

the "length" attribute indicates an advisory length of the linked content in octets. it's a hint about the content length of the representation returned when the IRI in the href attribute is mapped to a URI and dereferenced. the length attribute doesn't override the actual content length of the representation as reported by the underlying protocol, so the protocol still gets the final say ๐Ÿซถ link elements MAY have a length attribute.

4.2.8. The "atom:logo" Element ๐ŸŽ€

okay so the atom:logo element's content is an IRI reference [RFC3987] that points at an image giving the feed its visual identity ๐Ÿ–ผ๏ธโœจ basically its little face

atomLogo = element atom:logo {
   atomCommonAttributes,
   (atomUri)
}

bestie, the image SHOULD have an aspect ratio of 2 (horizontal) to 1 (vertical) ๐Ÿ“๐Ÿ’–

4.2.9. The "atom:published" Element ๐Ÿฆ‹

the atom:published element is a Date construct that marks an instant in time tied to an early moment in the entry's life cycle ๐ŸŒธ

atomPublished = element atom:published { atomDateConstruct }

typically, atom:published gets used for the initial creation or first availability of the resource ๐Ÿ“

4.2.10. The "atom:rights" Element ๐Ÿ’…

the atom:rights element is a Text construct that shares info about the rights held in and over an entry or feed ๐Ÿ”

atomRights = element atom:rights { atomTextConstruct }

the atom:rights element SHOULD NOT be used to convey machine-readable licensing information ๐Ÿ™ˆ that's not its job, babe

if an atom:entry doesn't have an atom:rights element, then the atom:rights element of the containing atom:feed (if there is one) is considered to apply to the entry ๐Ÿซถ

4.2.11. The "atom:source" Element ๐Ÿงš

if an atom:entry gets copied from one feed into another, then the source atom:feed's metadata (all the child elements of atom:feed other than the atom:entry elements) MAY be preserved inside the copied entry ๐Ÿ’œ you do that by adding an atom:source child element, as long as it isn't already in the entry, and putting some or all of the source feed's Metadata elements in as its children. that metadata SHOULD be preserved if the source atom:feed has any of the child elements atom:author, atom:contributor, atom:rights, or atom:category and those child elements aren't in the source atom:entry ๐Ÿ™Œ

atomSource =
   element atom:source {
      atomCommonAttributes,
      (atomAuthor*
       & atomCategory*
       & atomContributor*
       & atomGenerator?
       & atomIcon?
       & atomId?
       & atomLink*
       & atomLogo?
       & atomRights?
       & atomSubtitle?
       & atomTitle?
       & atomUpdated?
       & extensionElement*)
   }

the atom:source element is built so you can aggregate entries from different feeds and still keep track of each entry's source feed โœจ for that reason, Atom Processors doing this aggregation SHOULD include at least the required feed-level Metadata elements (atom:id, atom:title, and atom:updated) in the atom:source element ๐Ÿซถ

4.2.12. The "atom:subtitle" Element ๐ŸŒˆ

the atom:subtitle element is a Text construct that gives a human-readable description or subtitle for a feed ๐Ÿ“–

atomSubtitle = element atom:subtitle { atomTextConstruct }

4.2.13. The "atom:summary" Element ๐Ÿ“

the atom:summary element is a Text construct that carries a short summary, abstract, or excerpt of an entry โœ‚๏ธ

atomSummary = element atom:summary { atomTextConstruct }

it's not advisable for atom:summary to copy atom:title or atom:content, because Atom Processors might assume there's a useful summary when there isn't one ๐Ÿ™ˆ that's a whole vibe check gone wrong

4.2.14. The "atom:title" Element ๐Ÿ‘‘

the atom:title element is a Text construct that gives a human-readable title for an entry or feed ๐ŸŽ€

atomTitle = element atom:title { atomTextConstruct }

4.2.15. The "atom:updated" Element โญ

the atom:updated element is a Date construct for the most recent instant in time when an entry or feed was modified in a way the publisher considers significant ๐Ÿ•ฐ๏ธ so not every change will necessarily update this value, iykyk

atomUpdated = element atom:updated { atomDateConstruct }

publishers MAY change the value of this element over time ๐Ÿ’–

5. Securing Atom Documents ๐Ÿ”

because Atom is XML-based, existing XML security mechanisms can be used to secure its content ๐Ÿ›ก๏ธ

producers of feeds and/or entries, plus intermediaries who aggregate feeds and/or entries, might have totally valid reasons for signing and/or encrypting content that's otherwise unprotected ๐Ÿ’… for example, a merchant might digitally sign a message with a discount coupon for its products ๐Ÿ›๏ธ a bank that uses Atom to deliver customer statements is very likely to want to sign and encrypt those messages, to protect customers' financial information and assure them of its authenticity ๐Ÿฆ intermediaries might want to encrypt aggregated feeds so a passive observer can't tell what topics the recipient is into ๐Ÿ‘€ and of course, many other examples exist too ๐ŸŒธ

the algorithm requirements in this section are about the Atom Processor. they make sure a recipient can, at a minimum, handle messages that use the specified cryptographic algorithms. these requirements don't limit which algorithms the sender can choose ๐Ÿซถ

5.1. Digital Signatures โœ๏ธ

the root of an Atom Document (i.e., atom:feed in an Atom Feed Document, atom:entry in an Atom Entry Document) or any atom:entry element MAY have an Enveloped Signature, as described by XML-Signature and Syntax Processing [W3C.REC-xmldsig-core-20020212] ๐Ÿฆ‹

Atom Processors MUST NOT reject an Atom Document containing such a signature just because they can't verify it. they MUST continue processing and MAY tell the user that the signature failed to validate ๐Ÿ’Œ

in other words, having an element with the namespace URI "http://www.w3.org/2000/09/xmldsig#" and a local name of "Signature" as a child of the document element MUST NOT make an Atom Processor fail, just because it's there ๐Ÿ™…โ€โ™€๏ธ

other elements in an Atom Document MUST NOT be signed unless their definitions explicitly say they can be ๐Ÿšซ

Section 6.5.1 of [W3C.REC-xmldsig-core-20020212] requires support for Canonical XML [W3C.REC-xml-c14n-20010315]. however, lots of implementers skip it, because signed XML documents enclosed in other XML documents end up with broken signatures ๐Ÿ’€ so Atom Processors that verify signed Atom Documents MUST be able to canonicalize with the exclusive XML canonicalization method identified by the URI "http://www.w3.org/2001/10/xml-exc-c14n#", as specified in Exclusive XML Canonicalization [W3C.REC-xml-exc-c14n-20020718] โœจ

intermediaries like aggregators might need to add an atom:source element to an entry that doesn't have its own atom:source element. if that entry is signed, the addition breaks the signature ๐Ÿ˜ญ so a publisher of individually-signed entries should seriously consider adding an atom:source element to those entries before signing them ๐Ÿง  implementers should also be aware of the issues around using markup in the "xml:" namespace and how it interacts with canonicalization ๐Ÿ”

Section 4.4.2 of [W3C.REC-xmldsig-core-20020212] requires support for DSA signatures and recommends support for RSA signatures. but because RSA is way more popular in the market than DSA, Atom Processors that verify signed Atom Documents MUST be able to verify RSA signatures, and they do not need be able to verify DSA signatures ๐Ÿ’œ also, because there are security issues if the keying material for message authentication code (MAC) authentication isn't handled properly, Atom Documents SHOULD NOT use MACs for signatures ๐Ÿšซ๐Ÿ”‘

5.2. Encryption ๐Ÿ”’

the root of an Atom Document (i.e., atom:feed in an Atom Feed Document, atom:entry in an Atom Entry Document) MAY be encrypted, using the mechanisms described by XML Encryption Syntax and Processing [W3C.REC-xmlenc-core-20021210] ๐Ÿง

Section 5.1 of [W3C.REC-xmlenc-core-20021210] requires support of TripleDES, AES-128, and AES-256. Atom Processors that decrypt Atom Documents MUST be able to decrypt with AES-128 in Cipher Block Chaining (CBC) mode ๐ŸŒท

encryption based on [W3C.REC-xmlenc-core-20021210] does NOT ensure integrity of the original document ๐Ÿ‘€ there are known cryptographic attacks where someone who can't decrypt a message can still flip bits so that part or all of the decrypted message makes sense but means something different ๐Ÿ˜ฑ so Atom Processors that decrypt Atom Documents SHOULD check the integrity of the decrypted document, by verifying the hash in the signature (if there is one) in the document, or by verifying a hash of the document within the document (if there is one) ๐Ÿ›ก๏ธ

5.3. Signing and Encrypting ๐ŸŽ€

when an Atom Document is going to be both signed and encrypted, it's generally a good idea to sign the document first and then encrypt the signed document ๐Ÿซถ this gives integrity to the base document while encrypting all the information, including who signed it ๐Ÿคซ note that, if MACs are used for authentication, the order MUST be that the document is signed and then encrypted, and NOT the other way around ๐Ÿ’…

6. Extending Atom ๐Ÿงš

6.1. Extensions from Non-Atom Vocabularies ๐ŸŒˆ

this specification describes Atom's XML markup vocabulary. markup from other vocabularies ("foreign markup") can be used in an Atom Document ๐Ÿ’– and the atom:content element is designed to support arbitrary foreign markup, so go wild ๐Ÿฆ‹

6.2. Extensions to the Atom Vocabulary ๐Ÿ”ฎ

the Atom namespace is reserved for future forward-compatible revisions of Atom ๐ŸŒธ future versions of this spec could add new elements and attributes to the Atom markup vocabulary. software written to conform to this version of the spec won't be able to process that markup correctly and, honestly, won't even be able to tell it apart from markup error ๐Ÿ˜ตโ€๐Ÿ’ซ for the purposes of this discussion, unrecognized markup from the Atom vocabulary will be considered "foreign markup" ๐Ÿท๏ธ

6.3. Processing Foreign Markup ๐Ÿซง

Atom Processors that run into foreign markup in a location that's legal according to this specification MUST NOT stop processing or signal an error ๐Ÿ™…โ€โ™€๏ธ it might be that the Atom Processor can process the foreign markup correctly, and then it does โœ… otherwise, that markup is termed "unknown foreign markup" ๐Ÿคทโ€โ™€๏ธ

when unknown foreign markup shows up as a child of atom:entry, atom:feed, or a Person construct, Atom Processors MAY bypass the markup and any textual content, and they MUST NOT change their behavior because the markup is there ๐Ÿซถ

when unknown foreign markup is found in a Text Construct or atom:content element, software SHOULD ignore the markup and process any text content of foreign elements as though the surrounding markup weren't there ๐Ÿงผ

6.4. Extension Elements โœจ

Atom allows foreign markup anywhere in an Atom document, except where it's explicitly forbidden ๐ŸŽ‰ child elements of atom:entry, atom:feed, atom:source, and Person constructs are considered Metadata elements and are described below ๐Ÿ“‹ child elements of Person constructs are considered to apply to the construct ๐Ÿ‘‘ the role of other foreign markup is undefined by this specification ๐Ÿคทโ€โ™€๏ธ๐Ÿ’œ

6.4.1. Simple Extension Elements โœจ

Okay bestie, simple extension elements are the chill ones ๐Ÿงš A Simple Extension element MUST NOT have any attributes or child elements. It MAY contain character data or be empty ๐Ÿ’… Simple Extension elements are not Language-Sensitive.

simpleExtensionElement =
   element * - atom:* {
      text
   }

The element can be read as a simple property (a name/value pair) of the parent element around it ๐Ÿ’– The namespace-URI plus the local name of the element works as the property's name, and the character data inside it works as the value. If the element is empty, the value can be read as an empty string ๐Ÿซถ

6.4.2. Structured Extension Elements ๐ŸŒˆ

The root element of a Structured Extension element MUST have at least one attribute or child element ๐Ÿ˜ญ It MAY have attributes, it MAY contain well-formed XML content (including character data), or it MAY be empty. Structured Extension elements are Language-Sensitive, so they get the full main character treatment ๐Ÿ‘‘

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

The structure of a Structured Extension element, including the order of its child elements, could be significant ๐Ÿฆ‹

This specification doesn't interpret a Structured Extension element ๐Ÿ™ˆ The syntax of the XML inside it (and how the element relates to the element that contains it) is defined by the specification of the Atom extension.


7. IANA Considerations ๐Ÿ“‹

An Atom Document, when serialized as XML 1.0, can be identified with the following media type ๐ŸŽ€

MIME media type name:  application
MIME subtype name:  atom+xml
Mandatory parameters:  None.
Optional parameters:
   "charset":  This parameter has semantics identical to the charset
      parameter of the "application/xml" media type as specified in
      [RFC3023].
Encoding considerations:  Identical to those of "application/xml" as
   described in [RFC3023], Section 3.2.
Security considerations:  As defined in this specification.
   In addition, as this media type uses the "+xml" convention, it
   shares the same security considerations as described in [RFC3023],
   Section 10.
Interoperability considerations:  There are no known interoperability
   issues.
Published specification:  This specification.
Applications that use this media type:  No known applications
   currently use this media type.

Additional information:

Magic number(s):  As specified for "application/xml" in [RFC3023],
   Section 3.2.
File extension:  .atom
Fragment identifiers:  As specified for "application/xml" in
   [RFC3023], Section 5.
Base URI:  As specified in [RFC3023], Section 6.
Macintosh File Type code:  TEXT
Person and email address to contact for further information:  Mark
   Nottingham <mnot@pobox.com>
Intended usage:  COMMON
Author/Change controller:  IESG

This registry is maintained by IANA and starts out with five values: "alternate", "related", "self", "enclosure", and "via" ๐ŸŒธ New assignments are subject to IESG Approval, as outlined in [RFC2434]. Requests should be emailed to IANA, which will then forward the request to the IESG, asking for approval. The request should use this template:

o  Attribute Value: (A value for the "rel" attribute that conforms to
   the syntax rule given in Section 4.2.7.2)
o  Description:
o  Expected display characteristics:
o  Security considerations:

8. Security Considerations ๐Ÿ”’

Okay, this part is seriously important, so pay attention ๐Ÿšจ

8.1. HTML and XHTML Content

Text constructs and atom:content let you deliver HTML and XHTML ๐Ÿ’… Lots of elements in those languages are considered 'unsafe' because they open clients up to one or more types of attack ๐Ÿ˜ฌ Anyone building software that processes Atom should think carefully about how they handle every type of element when processing incoming (X)HTML in Atom Documents. For guidance, check the security sections of [RFC2854] and [HTML] โœจ

Atom Processors should pay particular attention to the security of the IMG, SCRIPT, EMBED, OBJECT, FRAME, FRAMESET, IFRAME, META, and LINK elements, but other elements might also have negative security properties ๐Ÿ’€

(X)HTML can either directly contain or indirectly reference executable content ๐Ÿ”ฅ

8.2. URIs

Atom Processors handle URIs. See Section 7 of [RFC3986] ๐Ÿฆ‹

8.3. IRIs

Atom Processors handle IRIs. See Section 8 of [RFC3987] ๐ŸŒˆ

8.4. Spoofing

Atom Processors should be aware of the potential for spoofing attacks, where an attacker publishes an atom:entry with the atom:id value of an entry from another feed, maybe with a falsified atom:source element that copies the atom:id of the other feed ๐Ÿ™ˆ For example, an Atom Processor could hide duplicate entries by showing only one entry from a set of entries with identical atom:id values. In that situation, the Atom Processor might also check whether the entries came from the same publisher before treating them as duplicates ๐Ÿง

8.5. Encryption and Signing

Atom Documents can be encrypted and signed using [W3C.REC-xmlenc-core-20021210] and [W3C.REC-xmldsig-core-20020212], respectively, and they are subject to the security considerations that come with using those ๐Ÿ”

Digital signatures provide authentication, message integrity, and non-repudiation with proof of origin ๐Ÿ’œ Encryption provides data confidentiality โœจ


9. References ๐Ÿ“š

9.1. Normative References

[HTML]     Raggett, D., Hors, A., and I. Jacobs, "HTML 4.01
           Specification", W3C REC REC-html401-19991224,
           December 1999,
           <http://www.w3.org/TR/1999/REC-html401-19991224>.

[MIMEREG]  Freed, N. and J. Klensin, "Media Type Specifications and
           Registration Procedures", BCP 13, RFC 4288, December 2005.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2822]  Resnick, P., "Internet Message Format", RFC 2822,
           April 2001.

[RFC2854]  Connolly, D. and L. Masinter, "The 'text/html' Media
           Type", RFC 2854, June 2000.

[RFC3023]  Murata, M., St. Laurent, S., and D. Kohn, "XML Media
           Types", RFC 3023, January 2001.

[RFC3066]  Alvestrand, H., "Tags for the Identification of
           Languages", BCP 47, RFC 3066, January 2001.

[RFC3339]  Klyne, G. and C. Newman, "Date and Time on the Internet:
           Timestamps", RFC 3339, July 2002.

[RFC3548]  Josefsson, S., "The Base16, Base32, and Base64 Data
           Encodings", RFC 3548, July 2003.

[RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
           Resource Identifier (URI): Generic Syntax", STD 66,
           RFC 3986, January 2005.

[RFC3987]  Duerst, M. and M. Suignard, "Internationalized Resource
           Identifiers (IRIs)", RFC 3987, January 2005.

[W3C.REC-xml-20040204]
           Yergeau, F., Paoli, J., Sperberg-McQueen, C., Bray, T.,
           and E. Maler, "Extensible Markup Language (XML) 1.0 (Third
           Edition)", W3C REC REC-xml-20040204, February 2004,
           <http://www.w3.org/TR/2004/REC-xml-20040204>.

[W3C.REC-xml-c14n-20010315]
           Boyer, J., "Canonical XML Version 1.0", W3C REC REC-xml-
           c14n-20010315, March 2001,
           <http://www.w3.org/TR/2001/REC-xml-c14n-20010315>.

[W3C.REC-xml-exc-c14n-20020718]
           Eastlake, D., Boyer, J., and J. Reagle, "Exclusive XML
           Canonicalization Version 1.0", W3C REC REC-xml-exc-c14n-
           20020718, July 2002,
           <http://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718>.

[W3C.REC-xml-infoset-20040204]
           Cowan, J. and R. Tobin, "XML Information Set (Second
           Edition)", W3C REC REC-xml-infoset-20040204,
           February 2004,
           <http://www.w3.org/TR/2004/REC-xml-infoset-20040204>.

[W3C.REC-xml-names-19990114]
           Hollander, D., Bray, T., and A. Layman, "Namespaces in
           XML", W3C REC REC-xml-names-19990114, January 1999,
           <http://www.w3.org/TR/1999/REC-xml-names-19990114>.

[W3C.REC-xmlbase-20010627]
           Marsh, J., "XML Base", W3C REC REC-xmlbase-20010627,
           June 2001,
           <http://www.w3.org/TR/2001/REC-xmlbase-20010627>.

[W3C.REC-xmldsig-core-20020212]
           Solo, D., Reagle, J., and D. Eastlake, "XML-Signature
           Syntax and Processing", W3C REC REC-xmldsig-core-20020212,
           February 2002,
           <http://www.w3.org/TR/2002/REC-xmldsig-core-20020212>.

[W3C.REC-xmlenc-core-20021210]
           Reagle, J. and D. Eastlake, "XML Encryption Syntax and
           Processing", W3C REC REC-xmlenc-core-20021210,
           December 2002,
           <http://www.w3.org/TR/2002/REC-xmlenc-core-20021210>.

[XHTML]    Altheim, M., Boumphrey, F., McCarron, S., Dooley, S.,
           Schnitzenbaumer, S., and T. Wugofski, "Modularization of
           XHTML[TM]", W3C REC REC-xhtml-modularization-20010410,
           April 2001, <http://www.w3.org/TR/2001/
           REC-xhtml-modularization-20010410>.

9.2. Informative References

[ISO.8601.1988]
           International Organization for Standardization, "Data
           elements and interchange formats - Information interchange
           - Representation of dates and times", ISO Standard 8601,
           June 1988.

[RELAX-NG] Clark, J., "RELAX NG Compact Syntax", December 2001,
           <http://www.oasis-open.org/committees/relax-ng/
           compact-20021121.html>.

[RFC2434]  Narten, T. and H. Alvestrand, "Guidelines for Writing an
           IANA Considerations Section in RFCs", BCP 26, RFC 2434,
           October 1998.

[W3C.NOTE-datetime-19980827]
           Wolf, M. and C. Wicksteed, "Date and Time Formats", W3C
           NOTE NOTE-datetime-19980827, August 1998,
           <http://www.w3.org/TR/1998/NOTE-datetime-19980827>.

[W3C.REC-xmlschema-2-20041028]
           Malhotra, A. and P. Biron, "XML Schema Part 2: Datatypes
           Second Edition", W3C REC REC-xmlschema-2-20041028,
           October 2004,
           <http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.

Appendix A. Contributors ๐Ÿซถ

The following people contributed to preliminary versions of this document: Tim Bray, Mark Pilgrim, and Sam Ruby ๐ŸŒŸ Norman Walsh provided the Relax NG schema. The content and concepts in here are a product of the Atom community and the Atompub Working Group ๐Ÿ’–

The Atompub Working Group has dozens of very active contributors who proposed ideas and wording for this document, including: Danny Ayers, James Aylett, Roger Benningfield, Arve Bersvendsen, Tim Bray, Dan Brickley, Thomas Broyer, Robin Cover, Bill de hOra, Martin Duerst, Roy Fielding, Joe Gregorio, Bjoern Hoehrmann, Paul Hoffman, Anne van Kesteren, Brett Lindsley, Dare Obasanjo, David Orchard, Aristotle Pagaltzis, John Panzer, Graham Parks, Dave Pawson, Mark Pilgrim, David Powell, Julian Reschke, Phil Ringnalda, Antone Roundy, Sam Ruby, Eric Scheid, Brent Simmons, Henri Sivonen, Ray Slakinski, James Snell, Henry Story, Asbjorn Ulsberg, Walter Underwood, Norman Walsh, Dave Winer, and Bob Wyman ๐Ÿ‘‘

Appendix B. RELAX NG Compact Schema โœจ

This appendix is informative ๐ŸŽ€ (so it's a helper, not a rule).

Okay so the Relax NG schema is super strict ๐Ÿ’… and it straight up excludes any elements in the Atom namespace that aren't defined in this revision of the spec. If an Atom Processor runs into that kind of markup, the rules for what to do are in Sections 6.2 and 6.3 ๐Ÿฆ‹. Read those, bestie!

# -*- 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

Authors' Addresses ๐ŸŒธ

Mark Nottingham (editor) ๐Ÿ’œ

EMail: mnot@pobox.com URI: http://www.mnot.net/

Robert Sayre (editor) ๐Ÿฆ‹

EMail: rfsayre@boswijck.com URI: http://boswijck.com


Copyright (C) The Internet Society (2005).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Intellectual Property ๐Ÿ”ฅ

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.


Acknowledgement ๐Ÿงš

Funding for the RFC Editor function is currently provided by the Internet Society. That's the end of RFC 4287, bestie! ๐ŸŒˆ๐Ÿ‘‘

๐Ÿ“ฆ where this page comes from