Full validation of Atom feeds containing extensions

5 May 2008

Makoto Murata and Hisashi Miyashita

Abstract

The RELAX NG schema in RFC 4287 (The Atom Syndication Format) does not provide full validation of Atom feeds containing extensions. Rather, this schema skips extension elements and attributes, even when extension elements further contain Atom feeds or entries. This document shows that ISO/IEC 19757-4 Namespace-based Validation Dispatching Language (NVDL for short) allows full validation of atom feeds containing extensions. NVDL decomposes atom feeds containing extensions into (1) extension-free atom and (2) extensions so that (1) and (2) are validated separately. As an example, an NVDL script for Google Calendar is presented. This NVDL script reveals validation errors of atom entries embedded in Google Calendar extension elements.

Note: All files used in this note are available at http://www.asahi-net.or.jp/~eb2m-mrt/atomextensions/atomextensions.zip.

1. Introduction

The RELAX NG schema (hereafter atom.rnc) in RFC 4287 (The Atom Syndication Format) does not provide full validation of atom feeds containing extensions. Rather, the schema focuses on top-level constructs of atom feeds; it skips extension elements and attributes, even when extension elements further contain constructs of atom feeds.

Some specifications (e.g., RFC 4685 (Atom Threading Extensions) for atom extensions provide schemas for extension elements and attributes. These extension schemas focus on extension elements and attributes, and are typically written in RELAX NG. However, such extension schemas are not referenced from atom.rnc. As a result, these schemas do not provide full validation of atom feeds containing extensions. They are useful for documentation, but they are not usable for validating atom feeds.

One might wonder whether atom.rnc and extension schemas can be combined to form a single RELAX NG schema against which atom feeds containing extensions are fully validated. To the best of our knowledge, our earlier work (Murata07) is the only example of such combined schemas. We combined a variation of atom.rnc and three schemas for atom extensions thereby successfully providing full validation. However, we do not believe that this all-in-one approach provides a reliable basis for full validation of atom and its extensions. The all-in-one approach requires that (1) schema authors understand schema customization techniques (e.g., the combine feature of RELAX NG) very well, (2) they avoid pitfalls caused by wildcards, and (3) they understand customization points of all schemas to be combined.

In this document, we advocate the use of Namespace-based Validation Dispatching Language (ISO/IEC 19757-4) for full validation of atom feeds containing extensions. Schema authors for atom extensions first create schemas dedicated to the extensions. They then create NVDL scripts for combining these schemas and atom.rnc. Controlled by NVDL scripts, the NVDL engine decomposes atom feeds containing extension elements or attributes into (1) extension-free atom and (2) extensions so that (1) and (2) are validated separately. As an example, an NVDL script for Google Calendar is presented. This NVDL script reveals that embedded atom entries in Google Calendar XML documents have validation errors.

2. NVDL scripts for atom

We introduce NVDL features step by step.

1) atom + foreign

We begin with a simple NVDL script. It invokes atom.rng and does not invoke other schemas.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
NVDL
open.nvdl

The point of this NVDL script is the <alow/> action in the anyNamespace element. This action allows foreign attributes and elements. Before an atom feed is validated against atom.rng (which is equivalent to atom.rnc), all foreign attributes and elements are removed by the NVDL engine.

<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
     startMode="root">
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng">
        <mode>
          <namespace ns="" match="attributes">
            <attach/>
          </namespace>
          <anyNamespace match="elements attributes">
            <allow/>
          </anyNamespace>
        </mode>
      </validate>
    </namespace>
  </mode>
</rules>

The first example in RFC 4287 (The Atom Syndication Format) and the example in 7.1.2 of Specifications/OpenSearch/1.1/Draft 3 are valid against this NVDL.script.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh open.nvdl simpleExample.xml
Open the NVDL file: open.nvdl
Validate the instance file: simpleExample.xml
simpleExample.xml is a valid XML document.
bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh open.nvdl openSearchExample.xml
Open the NVDL file: open.nvdl
Validate the instance file: openSearchExample.xml
openSearchExample.xml is a valid XML document.

2) atom + opensearch + foreign

This script is derived from the previous one by adding a context element, which controls the validation of foreign elements or attributes of atom:feed elements. The first namespace element within this context element specifies that openSearch11.rng be used for the validation of foreign elements of the namespace "http://a9.com/-/spec/opensearch/1.1/".

Given an atom feed, the NVDL engine first strips foreign elements and attributes. Foreign elements are validated against openSearch11.rng, if they are of the opensearch namespace and appear as children of atom:feed, All other foreign elements and attributes are allowed but removed before validation. Then, the atom feed without foreign elements and attributes are validated against atom.rng.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
NVDL
opensearch1.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
     startMode="root">
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng">
        <mode>
          <namespace ns="" match="attributes">
            <attach/>
          </namespace>
          <anyNamespace match="elements attributes">
            <allow/>
          </anyNamespace>
        </mode>
        <context path="feed">
          <mode>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng">
                <mode>
                  <namespace ns="" match="attributes">
                    <attach/>
                  </namespace>
                  <anyNamespace match="elements attributes">
                    <allow/>
                  </anyNamespace>
                </mode>
              </validate>
            </namespace>
            <namespace ns="" match="attributes">
              <attach/>
            </namespace>
            <anyNamespace match="elements attributes">
              <allow/>
            </anyNamespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

This script can be made more compact, since the child mode of <validate schema="atom.rng"> and that of <validate schema="openSearch11.rng"> are identical. We only have to create a named mode and reference to it with the attribute useMode.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
NVDL
opensearch2.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
    startMode="root">
  <mode name="allow-foreign">
    <namespace ns="" match="attributes">
      <attach/>
    </namespace>
    <anyNamespace match="elements attributes">
      <allow/>
    </anyNamespace>
  </mode>
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            <namespace ns="" match="attributes">
              <attach/>
            </namespace>
            <anyNamespace match="elements attributes">
              <allow/>
            </anyNamespace>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

Note that the namespace and anyNamespace elements in the anonymous mode are identical to the contents of the mode "allow-foreign". If we use XInclude, we can make the script even more compact.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
NVDL
opensearch3.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
       xmlns:xi="http://www.w3.org/2001/XInclude" startMode="root">
  <xi:include parser="xml" href="allow-foreign.nvdl"/>
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
    </namespace>
  </mode>
</rules>

Here allow-foreign.nvdl is

<?xml version="1.0"?>
<mode xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
    name="allow-foreign">
  <namespace ns="" match="attributes">
    <attach/>
  </namespace>
  <anyNamespace match="elements attributes">
    <allow/>
  </anyNamespace>
</mode>

If XInclude does not work, we can use internal parsed entities.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
NVDL
opensearch4.nvdl
<?xml version="1.0"?>
<!DOCTYPE rules [<!ENTITY allow-foreign-mode
"<mode name='allow-foreign'>
    <namespace ns='' match='attributes'>
      <attach/>
    </namespace>
    <anyNamespace match='elements attributes'>
      <allow/>
    </anyNamespace>
  </mode>">
]>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
     startMode="root">
  &allow-foreign-mode;
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            &allow-foreign-mode;
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

The example in 7.1.2 of Specifications/OpenSearch/1.1/Draft 3 are again valid against these NVDL script.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh opensearch4.nvdl openSearchExample.xml
Open the NVDL file: opensearch4.nvdl
Validate the instance file: openSearchExample.xml
openSearchExample.xml is a valid XML document.

Consider an incorrect example created by replacing

    <opensearch:startIndex>21</opensearch:startIndex>
    <opensearch:itemsPerPage>10</opensearch:itemsPerPage>
with
    <opensearch:startIndex>twenty-one</opensearch:startIndex>
    <opensearch:itemsPerPage>ten</opensearch:itemsPerPage>
. Then, we have validation errors as below:

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh opensearch4.nvdl openSearchIncorrectExample.xml
Open the NVDL file: opensearch4.nvdl
Validate the instance file: openSearchIncorrectExample.xml
file:openSearchIncorrectExample.xml Line:12, Col:62, 
(Validate(openSearch11.rng) file:opensearch4.nvdl, Line:22, Col:76): 
"twenty-one" does not satisfy the "int" type
file:openSearchIncorrectExample.xml Line:13, Col:59, 
(Validate(openSearch11.rng) file:opensearch4.nvdl, Line:22, Col:76): 
"ten" does not satisfy the "int" type
2 errors in openSearchIncorrectExample.xml

3) atom + opensearch + threading + history + foreign

Let us add two more extensions: RFC 4685 (Atom Threading Extensions), RFC 5005 (Feed Paging and Archiving). We use the XInclude version shown above as a basis.

Two context elements are added. The first one controls the validation of foreign elements or attributes of atom:entry elements. The second one, atom:link elements.

Three namespace elements are added. The first one appears within an existing context element. It handles the namespace "http://purl.org/syndication/history/1.0", to which fh:archive and fh:complete belong. The second one appears within the mode for the context atom:entry. It handles the namespace "http://purl.org/syndication/thread/1.0", to which thr:in-reply-to and thr:total belong. The third one appears within the mode for the context atom:link. Thanks to match="attributes", this namespace element handles attributes of the namespace "http://purl.org/syndication/thread/1.0", specificaly such as thr:count and thr:updated.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
threadingElements.rng (threadingElements.rnc) Extracted from RFC 4685 (Atom Threading Extensions), slightly modified, and converted to the XML syntax.
threadingAttributes.rng (threadingAttributes.rnc) Extracted from RFC 4685 (Atom Threading Extensions) and converted to the XML syntax.
archiveElements.rng (archiveElements.rnc) Extracted from RFC 5005 (Feed Paging and Archiving) and converted to the XML syntax.
NVDL
threading-and-history.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
       xmlns:xi="http://www.w3.org/2001/XInclude" startMode="root">
  <xi:include parser="xml" href="allow-foreign.nvdl"/>
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://purl.org/syndication/history/1.0">
              <validate schema="archiveElements.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
        <context path="entry">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://purl.org/syndication/thread/1.0">
              <validate schema="threadingElements.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
        <context path="link">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace match="attributes" 
                          ns="http://purl.org/syndication/thread/1.0">
              <validate schema="threadingAttributes.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

Two valid examples (link-good.xml and inReplyTo-good.xml) can be successfully validated.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh threading-and-history.nvdl link-good.xml
Open the NVDL file: threading-and-history.nvdl
Validate the instance file: link-good.xml
link-good.xml is a valid XML document.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh threading-and-history.nvdl inReplyTo-good.xml
Open the NVDL file: threading-and-history.nvdl
Validate the instance file: inReplyTo-good.xml
inReplyTo-good.xml is a valid XML document.

Errors in two invalid examples (link-bad.xml and inReplyTo-bad.xml) can be successfully detected.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh threading-and-history.nvdl link-bad.xml
Open the NVDL file: threading-and-history.nvdl
Validate the instance file: link-bad.xml
file:link-bad.xml Line:16, Col:67, (Validate(threadingAttributes.rng) 
file:threading-and-history.nvdl, Line:31, Col:83): attribute "thr:count" 
has a bad value: "z10" does not satisfy the "nonNegativeInteger" type
1 errors in link-bad.xml

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh threading-and-history.nvdl inReplyTo-bad.xml
Open the NVDL file: threading-and-history.nvdl
Validate the instance file: inReplyTo-bad.xml
file:inReplyTo-bad.xml Line:25, Col:51, (Validate(threadingElements.rng)
file:threading-and-history.nvdl, Line:23, Col:81): unexpected attribute "ype"
1 errors in inReplyTo-bad.xml

4) atom + opensearch + Google data/calendar + foreign

Google calendar XML documents are atom feeds containing extensions: opensearch, GData, and Google Calendar.

Permissible strucutres of Google calendar XML documents depends on the projection value used for retrieval. When the projection value is "full", <gd:feedLink> elements have links to comments; when the projection value is "composite", <gd:feedLink> elements contain <atom:feed>, which represent comments. More about this, see Google Calendar API Reference Guide.

An NVDL script for the projection value "full" is shown below.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
gCal.rng (gCal.rnc) Extracted from Google Calendar API Reference Guide, slightly modified, and converted to the XML syntax.
gacl.rng (gacl.rnc) Extracted from Google Calendar API Reference Guide, slightly modified, and converted to the XML syntax.
gd.rng (gd.rnc) Extracted from Common Elements: "Kinds" , which is one of the Goole Core Data API documents, modified, and converted to the XML syntax.
NVDL
full.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
       xmlns:xi="http://www.w3.org/2001/XInclude" startMode="root">
  <xi:include parser="xml" href="allow-foreign.nvdl"/>
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://schemas.google.com/g/2005">
              <validate schema="gd.rng">
                <context path="entryLink">
                   <mode>
                     <xi:include parser="xml" href="allow-foreign.nvdl"/>
                     <namespace ns="http://www.w3.org/2005/Atom">
                       <validate schema="atomEntry.rng" useMode="allow-foreign"/>
                     </namespace>
                   </mode>
                </context>
                <context path="feedLink">
                   <mode>
                     <xi:include parser="xml" href="allow-foreign.nvdl"/>
                     <namespace ns="http://www.w3.org/2005/Atom">
                       <validate schema="atomFeed.rng" useMode="allow-foreign"/>
                     </namespace>
                   </mode>
                </context>
              </validate>
            </namespace>
            <namespace ns="http://schemas.google.com/gCal/2005">
              <validate schema="gCal.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
        <context path="entry">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://schemas.google.com/g/2005">
              <validate schema="gd.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://schemas.google.com/gCal/2005">
              <validate schema="gCal.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://schemas.google.com/acl/2007">
              <validate schema="gacl.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

Let us validate an example document (full.xml) created by Google Calendar. This document is obtained from http://www.google.com/calendar/feeds/e1m39bcb04fuc79plrvmgmijho%40group.calendar.google.com/public/full.

Four errors are reported. gCal:uid and gCal:sequence elements occur in this document, but they are not mentioned anywhere in Google Calendar API Reference Guide. Thus, gCal.rng does not allow these elements.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh full.nvdl full.xml
Open the NVDL file: full.nvdl
Validate the instance file: full.xml
file:full.xml Line:52, Col:66, (Validate(gCal.rng) file:full.nvdl, Line:46, Col:68): 
  tag name "gCal:uid" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:full.xml Line:53, Col:35, (Validate(gCal.rng) file:full.nvdl, Line:46, Col:68): 
  tag name "gCal:sequence" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:full.xml Line:82, Col:66, (Validate(gCal.rng) file:full.nvdl, Line:46, Col:68): 
  tag name "gCal:uid" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:full.xml Line:83, Col:35, (Validate(gCal.rng) file:full.nvdl, Line:46, Col:68): 
  tag name "gCal:sequence" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
4 errors in full.xml

An NVDL script for the projection value "composite" is shown below. Observe that <atom:feed> elements within <gd:feedLink> elements are validated.

RELAX NG
atom.rng (atom.rnc) Extracted from RFC 4287 (The Atom Syndication Format) and converted to the XML syntax.
openSearch11.rng (openSearch11.rnc) Created from scratch
gCal.rng (gCal.rnc) Extracted from Google Calendar API Reference Guide, slightly modified, and converted to the XML syntax.
gacl.rng (gacl.rnc) Extracted from Google Calendar API Reference Guide, slightly modified, and converted to the XML syntax.
gd.rng (gd.rnc) Extracted from Common Elements: "Kinds" , which is one of the Goole Core Data API documents, modified, and converted to the XML syntax.
NVDL
composite.nvdl
<?xml version="1.0"?>
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0"
       xmlns:xi="http://www.w3.org/2001/XInclude" startMode="root">
  <xi:include parser="xml" href="allow-foreign.nvdl"/>
  <mode name="root">
    <namespace ns="http://www.w3.org/2005/Atom">
      <validate schema="atom.rng" useMode="allow-foreign">
        <context path="feed">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://a9.com/-/spec/opensearch/1.1/">
              <validate schema="openSearch11.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://schemas.google.com/g/2005">
              <validate schema="gd.rng">
                <context path="entryLink">
                   <mode>
                     <xi:include parser="xml" href="allow-foreign.nvdl"/>
                     <namespace ns="http://www.w3.org/2005/Atom">
                       <validate schema="atomEntry.rng" useMode="allow-foreign"/>
                     </namespace>
                   </mode>
                </context>
                <context path="feedLink">
                   <mode>
                     <xi:include parser="xml" href="allow-foreign.nvdl"/>
                     <namespace ns="http://www.w3.org/2005/Atom">
                       <validate schema="atomFeed.rng" useMode="allow-foreign"/>
                     </namespace>
                   </mode>
                </context>
              </validate>
            </namespace>
            <namespace ns="http://schemas.google.com/gCal/2005">
              <validate schema="gCal.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
        <context path="entry">
          <mode>
            <xi:include parser="xml" href="allow-foreign.nvdl"/>
            <namespace ns="http://schemas.google.com/g/2005">
              <validate schema="gd.rng">
                <mode>
                  <namespace ns="http://www.w3.org/2005/Atom">
                    <validate schema="atom.rng">
                      <mode>
                        <namespace ns="" match="attributes">
                          <attach/>
                        </namespace>
                        <anyNamespace match="elements attributes">
                          <allow/>
                        </anyNamespace>
                      </mode>
                    </validate>
                  </namespace>
                  <namespace ns="" match="attributes">
                    <attach/>
                  </namespace>
                  <anyNamespace match="elements attributes">
                    <allow/>
                  </anyNamespace>
                </mode>
              </validate>
            </namespace>
            <namespace ns="http://schemas.google.com/gCal/2005">
              <validate schema="gCal.rng" useMode="allow-foreign"/>
            </namespace>
            <namespace ns="http://schemas.google.com/acl/2007">
              <validate schema="gacl.rng" useMode="allow-foreign"/>
            </namespace>
          </mode>
        </context>
      </validate>
    </namespace>
  </mode>
</rules>

Again, let us validate an example document (composite.xml) created by Google Calendar. This document is obtained from http://www.google.com/calendar/feeds/e1m39bcb04fuc79plrvmgmijho%40group.calendar.google.com/public/composite. We have the same errors as previously.

bash-3.2$ sh c:/nvdl/SnRNV/msvnvdl.sh composite.nvdl composite.xml
Open the NVDL file: composite.nvdl
Validate the instance file: composite.xml
file:composite.xml Line:62, Col:66, (Validate(gCal.rng) file:composite.nvdl, Line:67, Col:68): 
  tag name "gCal:uid" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:composite.xml Line:63, Col:35, (Validate(gCal.rng) file:composite.nvdl, Line:67, Col:68): 
  tag name "gCal:sequence" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:composite.xml Line:102, Col:66, (Validate(gCal.rng) file:composite.nvdl, Line:67, Col:68): 
  tag name "gCal:uid" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
file:composite.xml Line:103, Col:35, (Validate(gCal.rng) file:composite.nvdl, Line:67, Col:68): 
  tag name "gCal:sequence" is not allowed. Possible tag names are: 
  <accesslevel>,<color>,<hidden>,<selected>,<timezone>
4 errors in composite.xml

References

  1. IETF RFC 4287, The Atom Syndication Format, http://tools.ietf.org/html/rfc4287.html
  2. IETF RFC 4685, Atom Threading Extensions, http://tools.ietf.org/html/rfc4685.html
  3. IETF RFC 5005, Feed Paging and Archiving, http://tools.ietf.org/html/rfc5005.html
  4. ISO/IEC 19757-4 Namespace-based Validation Dispatching Language, http://standards.iso.org/ittf/PubliclyAvailableStandards/c038615_ISO_IEC_19757-4_2006(E).zip
  5. Murata07, Schema for the combination of Atom and its extensions, http://www.imc.org/atom-syntax/mail-archive/msg19894.html
  6. Specifications/OpenSearch/1.1/Draft 3 - OpenSearch, http://www.opensearch.org/Specifications/OpenSearch/1.1#Example_of_OpenSearch_response_elements_in_Atom_1.0
  7. Google Calendar API Reference Guide, http://code.google.com/apis/calendar/reference.html
  8. Common Elements: "Kinds" , Goole Core Data API documents, http://code.google.com/apis/gdata/elements.html