Validating an Atom feed locally

Atom feeds have been invented in 2005. I prefer Atom over the four incompatible-with-each-other RSS formats because it is properly standardized.

After making an Atom feed, it is important to validate it to see if it's correct and every feed reader is able to understand it.

Online services

There are two web services to validate feeds:

Offline validation

At the time of writing, feedvalidator.org was broken and could not be used. Also during development, the feed most often is not available at a publicly accessible URL and thus validation by URL does not work. And copy&pasting is cumbersome. Validating the atom feed on your own machine without network requirements is to be preferred.

Atom feeds have to be validated on two levels:

  1. XML well-formedness
  2. Schema validity

Well-formedness

To check if your feed complies to the XML rules, simply check if it is well-formed:

$ xmllint --noout /path/to/feed.atom

If you get no output all is fine and the feed is valid XML (e.g. its tags are properly nested).

Schema validity

Apart from following the XML rules, Atom feeds also have to adhere to the rules that RFC 4287 defines. The RFC even contains a machine-readable Atom feed schema in appendix B: RELAX NG Compact Schema.

Unfortunately xmllint is not able to work with RELAX NG compact files, but trang can be used to convert .rnc to "normal" .rng files:

$ trang -I rnc -O rng atom.rnc atom.rng

Now we can use the atom.rng schema file to validate our feed:

$ xmllint --noout --relaxng atom.rng http://cweiske.de/tagebuch/feed/
http://cweiske.de/tagebuch/feed/ validates

XML schema

At the time of writing in 2017, I know of not a single working XML schema file for the Atom feed specification.

www.kbcafe.com/rss/atom.xsd.xml does not even detect a missing <id> tag thus cannot be trusted.

The OASIS CMIS atom feed schema is broken; xmllint reports an error when I try to use it:

complex type 'atomPersonConstruct': The content model is not determinist.

Simply use the atom.rng file linked above instead.

Written by Christian Weiske.

Comments? Please send an e-mail.