Atom协议标准中文版

最近准备做一些 RSS 相关的工作,但是发现除了 RSS 协议之外官方还提供了个 Atom 协议,算是继承自 RSS 并且进行了一些扩展,相对要比 RSS 复杂很多,而网上也没找到中文资料,阅读文档的时候就想着看都看了,那就顺便(并不)翻译成中文吧。

1. 介绍

Atom 是一种基于 XML 的文档格式,主要用于描述 Feed 相关的信息列表。

Feeds 流由很多 entries(条目)组成,每个条目都包含一组可扩展的附加元数据,例如标题等等。

1.1 实例

一个简短的单项 Atom Feed 文档:



   Example Feed
   
   2003-12-13T18:30:02Z
   
     John Doe
   
   urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6

   
     Atom-Powered Robots Run Amok
     
     urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a
     2003-12-13T18:30:02Z
     Some text.
   


或者一个更广泛的单项 Atom Feed 文档:



   dive into mark
   
     A <em>lot</em> of effort
     went into making this effortless
   
   2005-07-31T12:29:29Z
   tag:example.org,2003:3
   
   
   Copyright (c) 2003, Mark Pilgrim
   
     Example Toolkit
   
   
     Atom draft-07 snapshot
     
     
     tag:example.org,2003:3.2397
     2005-07-31T12:29:29Z
     2003-12-13T08:29:29-04:00
     
       Mark Pilgrim
       
       [email protected]
     
     
       Sam Ruby
     
     
       Joe Gregorio
     
     
       

[Update: The Atom draft is finished.]

1.2 命名空间与版本

本规范中描述的 XML 数据格式的 XML 命名空间 URI 是:

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

方便起见,可以简写为"Atom 1.0".

1.3 符号约定

该规范描述了两个工件的一致性:Atom Feed Documents 与 Atom Entry Documents。

另外也对 Atom 解析程序提出了一些要求。

该规范使用 "atom:" 命名空间前缀表示上一节中的命名空间。但这并不是规范中的标准,可以任意选择,你甚至可以用 "rss:" ,只要你喜欢。

本文档中的关键词 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 是被解释为 BCP_14, [RFC2119] 中描述的那样,以这些一致性目标为范围。

这里大概说下这几个关键词的意思:

  • MUST, REQUIRED, SHALL:规范绝对要求
  • MUST NOT, SHALL NOT:规范绝对禁止
  • SHOULD, RECOMMENDED:除非有正当理由,否则推荐这么做
  • SHOULD NOT, NOT RECOMMENDED:除非有正当理由,否则别这么做
  • MAY, OPTIONAL:中立,可选

2. Atom 文档

本规范描述了两种 Atom 文档:Atom Feed DocumentsAtom Entry Documents

Atom Feed Documents 用于描述 Atom feed(信息流),其中包含一些关于 feed 的元数据,以及与之相关联的 Entry(条目)。它的根结点是 atom:feed

Atom Entry Documents 仅用于描述一个 Atom Entry(条目),根结点为atom:entry

namespace atom = ""
start = atomFeed | atomEntry

这两种 Atom 文档同样都遵守 XML Information Set 规范。使用 XML 1.0 序列化。媒体类型为 application/atom+xml。Atom 文档必须是格式良好的 XML。

Atom 文档中的每个元素都有可能(MAY)包含一个xml:base XML 属性,这个属性的定义在这里[W3C.REC-xmlbase-20010627],大概可以理解为 baseUrl,即定义了该属性的元素下面的 url 可以使用相对路径加上这个 baseUrl。

Atom 文档中的每个元素都有可能(MAY)包含一个xml:lang XML属性,它表示该元素以及其子元素中内容的自然语言类型。

综上所述,Atom 通用属性可能会包含 xml:basexml:lang,以及一些未定义的属性。因此我们做出如下定义。

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

另外,Atom 是一种可扩展的格式,关于如何进行扩展后面会详细介绍。

3. Atom 通用结构(Common Atom Constructs)

许多 Atom 的元素共享一些共同的结构。 本节定义了这些结构和它们的要求,以方便相应的元素定义的引用。

当一个元素被认定为是一种特殊的结构时,它就继承了本节中该结构定义中的相应要求。

请注意,在 Date 结构体或任何 IRI 中都必须(MUST)不能有任何空白。 一些XML的实现在默认情况下会在值周围插入空白,这样的实现会发出无效的 Atom 文档。

3.1 文本结构(Text Constructs)

一个文本结构包含人类可读的文本,通常内容比较少。文本结构的内容是对语言敏感的。

定义如下:

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

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

atomTextConstruct = atomPlainTextConstruct | atomXHTMLTextConstruct

3.1.1 “type” 属性

文本结构可以有一个 type 属性。 其值必须(MUST)是 texthtmlxhtml 中的一个。

如果未提供 type 属性,则必须视为 text 类型。下面分别介绍这三种类型。

3.1.1.1 Text

举个例子,下面是一个包含文本内容的 title:


     Less: <


首先,text 类型的文本是决不能包含子元素的,该类型是为了直接呈现给用户的,需要保证其直接的可读性。

其次,Atom 的处理软件可能会删除其中的一些空白字符,通过某种文字排版技术进行排版。

3.1.1.2 HTML

再举个例子,下面是一个包含 HTML 内容的 title:


     Less: <em> &lt; </em>


同样,html 类型的文本也是决不能包含子元素的,应该将其视作 HTML 格式来读取并显示。

其中包含的任何标记都应被转义后再显示。事实上,html 标记内容应该(SHOULD)是可以直接在

中显示的。

3.1.1.3 XHTML

下面是一个包含 XHTML 内容的 title:


     <xhtml:div>
       Less: <xhtml:em> < </xhtml:em>
     </xhtml:div>


xhtml 标记的内容必须是是一个单独的 XHTML div 元素,同时也应该适合作为 XHTML 进行处理。 元素本身并不应该被显示,应该按照处理程序转义之后再将其展示。

下面是另一个标准的例子:

...
 
    
This is XHTML content.
... This is XHTML content. ...

下面的例子假设 XHTML 命名空间已经在此之前被绑定到到文档中的 “xh” 前缀。

...

  
     This is XHTML content.
  

...

3.2 Person Constructs

Person Construct 是用于描述类似于人类、公司的元素。

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

Person construct 主要包含了三个属性:name,uri,email,下面分别看下。

3.2.1 “atom:name” 元素

atom:name 元素内容表示一个人类可读的人名。其内容是语言敏感的(Language-Sensitive)。

Person Construct 必须包含一个 name 元素。

3.2.2 “atom:uri” 元素

atom:uri 元素包含一个关于这个人的 IRI,Person Construct 中可能(MAY)包含一个 atom:uri 元素,但是其个数必须不能(MUST NOT)超过一个。

3.2.3 “atom:email” 元素

atom:email 元素代表关于这个人的邮箱地址,Person Construct 中可能(MAY)包含一个 atom:email 元素,但是其个数必须不能(MUST NOT)超过一个。

3.3 Date Constructs

Person Construct 是用于描述日期时间的元素。其格式必须遵守 [RFC3339] 中对 date-time 的定义。此外,必须使用大写字母 “T” 来分隔日期和时间,如果没有数字时区偏移,则必须使用大写字母 "Z" 结尾。

atomDateConstruct =
    atomCommonAttributes,
    xsd:dateTime

下面是一些正确的例子:

2003-12-13T18:30:02Z
2003-12-13T18:30:02.25Z
2003-12-13T18:30:02+01:00
2003-12-13T18:30:02.25+01:00

日期最好(SHOULD)尽可能的准确。

4. Atom 元素定义

4.1 Container Elements(容器元素)

4.1.1 “atom:feed” 元素

atom:feed 元素是 Atom Feed Document 的顶层元素,被用作于元数据以及与之相关的元素的容器。其内容包含一些元数据以及零个或多个 atom:entry 元素。

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

本规范未规定 “atom:entry” 的顺序,其顺序没有意义。

本规范对 atom:feed 元素的子元素做出如下定义:

  • 必须(MUST)包含一个或多个 atom:author 元素,除非其子 atom:entry 元素中至少包含一个 atom:author 元素。
  • 可能(MAY)包含任意数量的 atom:category 元素
  • 可能包含任意数量的 atom:contributor 元素
  • 必须不能(MUST NOT)包含超过一个的 atom:generator 元素
  • 必须不能包含超过一个的 atom:icon 元素
  • 必须不能包含超过一个的 atom:logo 元素
  • 必须包含一个 atom:id 元素
  • 应当(SHOULD)包含一个 atom:link 元素,且其中包含 rel=”relf” 属性,用于表示该文档的首选URL。
  • 必须不能包含超过一个 rel 属性值为 "alternate"atom:link 元素
  • 除了上面说的之外,还可能额外附加一些 atom:link 元素
  • 必须不能包含超过一个 atom:rights 元素
  • 必须不能包含超过一个 atom:subtitle 元素
  • 必须包含一个 atom:title 元素
  • 必须包含一个 atom:updated 元素

如果一个 Atom Feed 文档中包含多个 atom:id 相同的 atom:entry ,那么他们的 atom:updated 中的时间戳应该是不同的。

处理程序可以自己选择显示方式,例如选择最新的 atom:entry

4.1.1.1 提供文本内容

根据经验,包含文本内容的 Feed 效果会更好,假如应用程序中包含一个文本搜索功能,需要依靠少量的文本进行搜索,那么文本内容就会比较有用。

因此,建议每个 atom:entry 都提供一个非空的 atom:title 元素,一个非空的 atom:content 元素,如果不提供 atom:content 可以提供一个非空的 atom:summary 元素。

4.1.2 “atom:entry” 元素

atom:entry 表示一个单独的条目,是其元数据以及相关数据的容器。

其可作为 atom:feed 元素的子元素出现,也可以作为一个独立的文档(即顶层元素)出现。

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

本规范同样没有规定 atom:entry 子元素的顺序,所以其顺序没有意义。

本规范对 atom:entry 元素的子元素做出如下定义:

  • 必须包含一个或多个 atom:author 元素,除非 atom:entry 包含一个包含 atom:author 元素的 atom:source 元素,或者 atom:feed 元素中包含 atom:author 元素。
  • 可能包含任意数量的 atom:category 元素
  • 必须不能包含超过一个的 atom:content 元素
  • 可能包含任意数量的 atom:contributor 元素
  • 必须包含一个 atom:id 元素
  • 如果其中未包含 atom:content 元素,则必须包含至少一个属性 rel=alternateatom:link 元素
  • 必须不能包含超过一个属性 rel=alternateatom:link 元素
  • 除了上面说的之外,还可能额外附加一些 atom:link 元素
  • 必须不能包含超过一个的 atom:published 元素
  • 必须不能包含超过一个的 atom:rights 元素
  • 必须不能包含超过一个的 atom:source 元素
  • 下面两种情况下,必须包含一个 atom:summary 元素:
    • atom:content 元素中包含一个 src 属性
    • atom:content 元素内容使用 Base64 加密,例如 atom:contenttype 属性是一个 MIME 媒体类型,但并不是 XML 类型,即并不是以 text/ 开始,且不以 /xml+xml 结尾。
  • 必须不能包含超过一个 atom:summary 元素
  • 必须包含一个 atom:title 元素
  • 必须包含一个 atom:updated 元素

4.1.3 "atom:content” 元素

atom:content 元素包含或者链接到条目的内容。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

如上所示,atomContent 包含四种类型的内容。

4.1.3.1 “type” 属性

atom:content 元素中,type 属性可能是 text/html/xhtml 中的一种,否则它必须是 MIME 媒体类型,但不可以是组合类型。

如果既没有提供 type 属性也没有提供 src 属性,那么应该按照 text 类型来进行处理。

4.1.3.2 “src” 属性

atom:content 元素可能包含一个 src 属性,其值必须是一个 IRI,如果提供了 src 属性,则 atom:content 内容必须为空。

如果提供了 src 属性,则应当提供 type 属性,且 type 属性必须是 MIME 媒体类型而不是 text/html/xhtml。此时,type 的值并非对应 IRI 的真正类型,当访问该 IRI 时还是要以 IRI 返回的媒体类型为准。

4.1.3.3 处理模式

Atom 文档以及 Atom 处理程序必须遵守以下规则。

  1. 如果 type 值为 text,atom:content 必须不能包含子元素,且内容将会被排版后直接显示,需要保证其可读性。
  2. 如果 type 值为 html,atom:content 必须不能包含子元素且需要是能被处理的 HTML,需要将其解析显示。
  3. 如果 type 值为 xhtml,atom:content 必须是单个 XHTML div 且需要是能被处理的 XHTML。
  4. 如果 type 值是个 XML 媒体类型或者以 +xml 或者 /xml 结尾,可能会包含子元素,且应当可以按照指定的格式进行处理,如果 src 属性未提供,一般可以认为 atom:content 元素包含单个子元素,且该元素是指定格式的 XML 文档的根元素。
  5. 如果 type 值以 text/ 开始,atom:content 必须不能包含子元素。
  6. 除了上面的 type 类型之外,atom:content 内容必须是个合法的 Base64 加密数据。

4.1.3.4 例子

XHTML inline:

...
 
    
This is XHTML content.
... This is XHTML content. ...

下面的例子假设 XHTML 命名空间已经在此之前被绑定到到文档中的 “xh” 前缀。

...
 
    
       This is XHTML content.
    
 
 ...

4.2 Metadata 元素

4.2.1 "atom:author” 元素

atom:author 是上面介绍过的 Person 结构(Person Construct),被用来表示 feed 或者 entry 的作者。

atomAuthor = element atom:author { atomPersonConstruct }

如果 atom:entry 元素中未包含 atom:author 元素,那么可以用 atom:source 中的 atom:author 元素,如果上述位置都不包含 atom:author 元素,那么可以用 atom:feed 中的 atom:author 元素。

4.2.2 "atom:category” 元素

atom:category 描述了关于这个 entry 或者 feed 的种类信息。本规范并为对其内容作出任何规定。

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

4.2.2.1 "term” 属性

term 属性表示 entry 或者 feed 所属种类的标识字符串。atom:category 元素必须包含一个 term 属性。

4.2.2.2 "scheme” 属性

scheme 属性是个表示分类方案的 IRI,atom:category 元素可能会包含它。

4.2.2.3 "label” 属性

label 属性提供了一个人类可读的标签用于显示在终端程序中,不应该对其中内容做转义,这不是标记,atom:category 元素可能会包含它。

4.2.3 "atom:contributor” 元素

atom:contributor 元素同样是个 Person 结构(Person Construct),表示该 entry 或者 feed 的贡献者。

4.2.4 "atom:generator” 元素

atom:generator 用于标识生成 feed 的代理,用于调试或者其他目的。

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

如果元素提供了内容,那么必须是人类可读的文本,不应该对其内容做转义。

atom:generator 元素可能会包含一个 uri 属性,其值必须为 IRI。

atom:generator 元素可能会包含一个 version 属性,表示代理的版本。

4.2.5 "atom:icon” 元素

atom:icon 元素内容是一个 IRI,是 feed 的标识图像。

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

这个图片的长宽比应当是一比一的,并且应当适合小尺寸展示。

4.2.6 "atom:id” 元素

atom:id 元素表示一个永久且普遍唯一的 entry 或 feed 标识符。

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

内容必须是 IRI,请注意这里的 IRI 并不包含相对引用。

当 Atom 文档被迁移、升级、聚合、再版、输出或者导入,atom:id 都必须不能改变。

4.2.7 "atom:link” 元素

atom:link 元素定义了从 entry/feed 到 Web 的引用,本规范对该元素的内容未做任何定义。

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 "href” 属性

href 属性包含了连接的 IRI,atom:link 元素必须包含一个 href 属性,其值必须是 IRI 引用。

4.2.7.2 "rel” 属性

atom:link 元素可能包含一个 rel 属性,用于标识 link 关系类型。如果未提供 rel 属性,则 link 元素必须被解释为 alternate 类型。

rel 属性的值必须是个符合 RFC3987 规范的非空的字符串。

本规范为 rel 定义了五个初始值:

  1. alternate:表示 href 属性值的 IRI 标识了元素内容所描述内容的资源的另一个替代版本。
  2. related:表示 href 属性值的 IRI 标识了与元素内容相关的资源。
  3. self:表示 href 属性值的 IRI 标识了与元素内容相同的资源。
  4. enclosure:表示 href 属性值的 IRI 可能标识一个大尺寸资源,可能需要特殊处理,此时应当提供 length 属性。
  5. vie:表示 href 属性值的 IRI 标识了元素的信息来源。

4.2.7.3 “type” 属性

在 link 元素中,type 属性是个建议性的媒体类型:它是一个关于表示类型的提示,当引用 href 属性的值时,是预期会返回的类型。

需要注意的是,改类型属性并不覆盖实际的媒体类型和表示方法。

Link 元素可能包含一个 type 属性,其值必须遵守 MIME 媒体类型规范。

4.2.7.4 "hreflang” 属性

hreflang 属性描述了 href 属性所指向资源的语言,当与 rel=”alternate” 结合使用时,意味着该条目的翻译版本。

4.2.7.5 "title” 属性

title 属性是关于这个 link 的人类可读的描述,不需要对其内容进行转义,Link 元素可能包含它。

4.2.7.6 "length” 属性

length 属性标识了连接内容的建议长度(以八位字节为单位),但并不能保证其实际长度,Link 元素中可能包含它。

4.2.8 "atom:logo” 元素

atom:logo 元素内容是一个 IRI,是 feed 的标识图像。

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

图像应的宽高比应该是2:1的。

4.2.9 "atom:published” 元素

atom:published 元素是个 Date Construct,表示 entry 生命周期中早期的事件的时间。

atomPublished = element atom:published { atomDateConstruct }

通常情况下,表示 entry 的创建时间或者首次可用时间。

4.2.10 "atom:rights” 元素

atom:rights ****元素是个 Text Construct(文本结构),表示 entry/feed 的版权信息。

atomRights = element atom:rights { atomTextConstruct }

atom:rights ****元素不应当是机器语言描述的许可信息。

如果 atom:entry 中不包含 atom:rights 元素,那么 atom:feed 中的 atom:rights 元素则适用于此 entry。

4.2.11 "atom:source” 元素

如果一个 atom:entry 从另一个 feed 中复制过来,那么源 atom:feed 中的元数据可能会被隐藏,并且加入到 atom:source 元素的子元素中去。

如果源 atom:feed 中包含 atom:authoratom:contributoratom:rights 以及 atom:category 且这些子元素在源 atom:entry 中不存在,那么应该这几个数据应该被保留。

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

4.2.12 "atom:subtitle” 元素

atom:subtitle 元素是个人类可读的 Text Construct(文本构造器),被当做 feed 的描述或者子标题。

atomSubtitle = element atom:subtitle { atomTextConstruct }

4.2.13 "atom:summary” 元素

atom:summary 元素是个人类可读的 Text Construct(文本构造器),用于描述 entry 的摘要、摘录等。

atomSummary = element atom:summary { atomTextConstruct }

不建议让 atom:summary 元素与 atom:titleatom:content 重复。

4.2.14 "atom:title” 元素

atom:title 元素是个人类可读的 Text Construct(文本构造器),用于描述 entry/feed 的标题。

atomTitle = element atom:title { atomTextConstruct }

4.2.15 "atom:updated” 元素

atom:updated 是个 Date Construct(日期构造器) ,表示 entry/feed 的最近一次的修改时间。

atomUpdated = element atom:updated { atomDateConstruct }

发布者可能会随着时间推移修改这个元素的值。

结尾

Atom 协议总体就这么多,本人才疏学浅,如有出错请谅解,另外还有一些其他附加内容,奈何精力有限,且暂时对本人没有帮助,就没有对其翻译。

除了上面的文章外,我还在写一个 Kotlin 平台的 RSS 与 Atom 协议的序列化反序列化实现,过几天会完成,需要的可以关注我的更新。

附录

Atom 协议标准地址:*https://datatracker.ietf.org/doc/html/rfc4287*

你可能感兴趣的:(Atom协议标准中文版)