Add a basic test of the OPDS stream. re #96
This commit is contained in:
parent
4624cc2c32
commit
f3be411c88
55
test/OPDSTest.php
Normal file
55
test/OPDSTest.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
require_once (dirname(__FILE__) . "/config_test.php");
|
||||
require_once (dirname(__FILE__) . "/../book.php");
|
||||
require_once (dirname(__FILE__) . "/../OPDS_renderer.php");
|
||||
|
||||
define ("OPDS_RELAX_NG", dirname(__FILE__) . "/opds_catalog_1_1.rng");
|
||||
define ("JING_JAR", dirname(__FILE__) . "/jing.jar");
|
||||
define ("TEST_FEED", dirname(__FILE__) . "/text.atom");
|
||||
|
||||
class OpdsTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
|
||||
function opdsValidateSchema($feed) {
|
||||
$path = "";
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
// huge hack, not proud about it
|
||||
$path = "c:\\Progra~1\\Java\\jre7\\bin\\";
|
||||
}
|
||||
$res = system($path . 'java -jar ' . JING_JAR . ' ' . OPDS_RELAX_NG . ' ' . $feed);
|
||||
if ($res != '') {
|
||||
echo 'RelaxNG validation error: '.$res;
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testPageIndex ()
|
||||
{
|
||||
global $config;
|
||||
$page = Base::PAGE_INDEX;
|
||||
$query = NULL;
|
||||
$search = NULL;
|
||||
$qid = NULL;
|
||||
$n = "1";
|
||||
$database = NULL;
|
||||
|
||||
$_SERVER['QUERY_STRING'] = "";
|
||||
|
||||
$currentPage = Page::getPage ($page, $qid, $query, $n);
|
||||
$currentPage->InitializeContent ();
|
||||
|
||||
$OPDSRender = new OPDSRenderer ();
|
||||
|
||||
file_put_contents (TEST_FEED, $OPDSRender->render ($currentPage));
|
||||
$this->AssertTrue ($this->opdsValidateSchema (TEST_FEED));
|
||||
file_put_contents (TEST_FEED, str_replace ("id>", "ido>", $OPDSRender->render ($currentPage)));
|
||||
$this->AssertFalse ($this->opdsValidateSchema (TEST_FEED));
|
||||
|
||||
$_SERVER['QUERY_STRING'] = NULL;
|
||||
}
|
||||
|
||||
}
|
598
test/atom.rng
Normal file
598
test/atom.rng
Normal file
|
@ -0,0 +1,598 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
-*- rnc -*-
|
||||
RELAX NG Compact Syntax Grammar for the
|
||||
Atom Format Specification Version 11
|
||||
-->
|
||||
<grammar ns="http://www.w3.org/1999/xhtml" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:s="http://www.ascc.net/xml/schematron" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
<start>
|
||||
<choice>
|
||||
<ref name="atomFeed"/>
|
||||
<ref name="atomEntry"/>
|
||||
</choice>
|
||||
</start>
|
||||
<!-- Common attributes -->
|
||||
<define name="atomCommonAttributes">
|
||||
<optional>
|
||||
<attribute name="xml:base">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="xml:lang">
|
||||
<ref name="atomLanguageTag"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<ref name="undefinedAttribute"/>
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
<!-- Text Constructs -->
|
||||
<define name="atomPlainTextConstruct">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<choice>
|
||||
<value>text</value>
|
||||
<value>html</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<text/>
|
||||
</define>
|
||||
<define name="atomXHTMLTextConstruct">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="type">
|
||||
<value>xhtml</value>
|
||||
</attribute>
|
||||
<ref name="xhtmlDiv"/>
|
||||
</define>
|
||||
<define name="atomTextConstruct">
|
||||
<choice>
|
||||
<ref name="atomPlainTextConstruct"/>
|
||||
<ref name="atomXHTMLTextConstruct"/>
|
||||
</choice>
|
||||
</define>
|
||||
<!-- Person Construct -->
|
||||
<define name="atomPersonConstruct">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<interleave>
|
||||
<element name="atom:name">
|
||||
<text/>
|
||||
</element>
|
||||
<optional>
|
||||
<element name="atom:uri">
|
||||
<ref name="atomUri"/>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="atom:email">
|
||||
<ref name="atomEmailAddress"/>
|
||||
</element>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<ref name="extensionElement"/>
|
||||
</zeroOrMore>
|
||||
</interleave>
|
||||
</define>
|
||||
<!-- Date Construct -->
|
||||
<define name="atomDateConstruct">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<data type="dateTime"/>
|
||||
</define>
|
||||
<!-- atom:feed -->
|
||||
<define name="atomFeed">
|
||||
<element name="atom:feed">
|
||||
<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.</s:assert>
|
||||
</s:rule>
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<interleave>
|
||||
<zeroOrMore>
|
||||
<ref name="atomAuthor"/>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<ref name="atomCategory"/>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<ref name="atomContributor"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomGenerator"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomIcon"/>
|
||||
</optional>
|
||||
<ref name="atomId"/>
|
||||
<zeroOrMore>
|
||||
<ref name="atomLink"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomLogo"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomRights"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomSubtitle"/>
|
||||
</optional>
|
||||
<ref name="atomTitle"/>
|
||||
<ref name="atomUpdated"/>
|
||||
<zeroOrMore>
|
||||
<ref name="extensionElement"/>
|
||||
</zeroOrMore>
|
||||
</interleave>
|
||||
<zeroOrMore>
|
||||
<ref name="atomEntry"/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:entry -->
|
||||
<define name="atomEntry">
|
||||
<element name="atom:entry">
|
||||
<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:assert>
|
||||
</s:rule>
|
||||
<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.</s:assert>
|
||||
</s:rule>
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<interleave>
|
||||
<zeroOrMore>
|
||||
<ref name="atomAuthor"/>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<ref name="atomCategory"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomContent"/>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<ref name="atomContributor"/>
|
||||
</zeroOrMore>
|
||||
<ref name="atomId"/>
|
||||
<zeroOrMore>
|
||||
<ref name="atomLink"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomPublished"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomRights"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomSource"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomSummary"/>
|
||||
</optional>
|
||||
<ref name="atomTitle"/>
|
||||
<ref name="atomUpdated"/>
|
||||
<zeroOrMore>
|
||||
<ref name="extensionElement"/>
|
||||
</zeroOrMore>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:content -->
|
||||
<define name="atomInlineTextContent">
|
||||
<element name="atom:content">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<choice>
|
||||
<value>text</value>
|
||||
<value>html</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<text/>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<define name="atomInlineXHTMLContent">
|
||||
<element name="atom:content">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="type">
|
||||
<value>xhtml</value>
|
||||
</attribute>
|
||||
<ref name="xhtmlDiv"/>
|
||||
</element>
|
||||
</define>
|
||||
<define name="atomInlineOtherContent">
|
||||
<element name="atom:content">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<ref name="atomMediaType"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<define name="atomOutOfLineContent">
|
||||
<element name="atom:content">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<ref name="atomMediaType"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<attribute name="src">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</define>
|
||||
<define name="atomContent">
|
||||
<choice>
|
||||
<ref name="atomInlineTextContent"/>
|
||||
<ref name="atomInlineXHTMLContent"/>
|
||||
<ref name="atomInlineOtherContent"/>
|
||||
<ref name="atomOutOfLineContent"/>
|
||||
</choice>
|
||||
</define>
|
||||
<!-- atom:author -->
|
||||
<define name="atomAuthor">
|
||||
<element name="atom:author">
|
||||
<ref name="atomPersonConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:category -->
|
||||
<define name="atomCategory">
|
||||
<element name="atom:category">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="term"/>
|
||||
<optional>
|
||||
<attribute name="scheme">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="label"/>
|
||||
</optional>
|
||||
<ref name="undefinedContent"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:contributor -->
|
||||
<define name="atomContributor">
|
||||
<element name="atom:contributor">
|
||||
<ref name="atomPersonConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:generator -->
|
||||
<define name="atomGenerator">
|
||||
<element name="atom:generator">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="uri">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="version"/>
|
||||
</optional>
|
||||
<text/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:icon -->
|
||||
<define name="atomIcon">
|
||||
<element name="atom:icon">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<ref name="atomUri"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:id -->
|
||||
<define name="atomId">
|
||||
<element name="atom:id">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<ref name="atomUri"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:logo -->
|
||||
<define name="atomLogo">
|
||||
<element name="atom:logo">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<ref name="atomUri"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:link -->
|
||||
<define name="atomLink">
|
||||
<element name="atom:link">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="href">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="rel">
|
||||
<choice>
|
||||
<ref name="atomNCName"/>
|
||||
<ref name="atomUri"/>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<ref name="atomMediaType"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="hreflang">
|
||||
<ref name="atomLanguageTag"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="title"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="length"/>
|
||||
</optional>
|
||||
<ref name="undefinedContent"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:published -->
|
||||
<define name="atomPublished">
|
||||
<element name="atom:published">
|
||||
<ref name="atomDateConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:rights -->
|
||||
<define name="atomRights">
|
||||
<element name="atom:rights">
|
||||
<ref name="atomTextConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:source -->
|
||||
<define name="atomSource">
|
||||
<element name="atom:source">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<interleave>
|
||||
<zeroOrMore>
|
||||
<ref name="atomAuthor"/>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<ref name="atomCategory"/>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
<ref name="atomContributor"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomGenerator"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomIcon"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomId"/>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<ref name="atomLink"/>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
<ref name="atomLogo"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomRights"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomSubtitle"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomTitle"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="atomUpdated"/>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<ref name="extensionElement"/>
|
||||
</zeroOrMore>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:subtitle -->
|
||||
<define name="atomSubtitle">
|
||||
<element name="atom:subtitle">
|
||||
<ref name="atomTextConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:summary -->
|
||||
<define name="atomSummary">
|
||||
<element name="atom:summary">
|
||||
<ref name="atomTextConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:title -->
|
||||
<define name="atomTitle">
|
||||
<element name="atom:title">
|
||||
<ref name="atomTextConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- atom:updated -->
|
||||
<define name="atomUpdated">
|
||||
<element name="atom:updated">
|
||||
<ref name="atomDateConstruct"/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- Low-level simple types -->
|
||||
<define name="atomNCName">
|
||||
<data type="string">
|
||||
<param name="minLength">1</param>
|
||||
<param name="pattern">[^:]*</param>
|
||||
</data>
|
||||
</define>
|
||||
<!-- Whatever a media type is, it contains at least one slash -->
|
||||
<define name="atomMediaType">
|
||||
<data type="string">
|
||||
<param name="pattern">.+/.+</param>
|
||||
</data>
|
||||
</define>
|
||||
<!-- As defined in RFC 3066 -->
|
||||
<define name="atomLanguageTag">
|
||||
<data type="string">
|
||||
<param name="pattern">[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*</param>
|
||||
</data>
|
||||
</define>
|
||||
<!--
|
||||
Unconstrained; it's not entirely clear how IRI fit into
|
||||
xsd:anyURI so let's not try to constrain it here
|
||||
-->
|
||||
<define name="atomUri">
|
||||
<text/>
|
||||
</define>
|
||||
<!-- Whatever an email address is, it contains at least one @ -->
|
||||
<define name="atomEmailAddress">
|
||||
<data type="string">
|
||||
<param name="pattern">.+@.+</param>
|
||||
</data>
|
||||
</define>
|
||||
<!-- Simple Extension -->
|
||||
<define name="simpleExtensionElement">
|
||||
<element>
|
||||
<anyName>
|
||||
<except>
|
||||
<nsName ns="http://www.w3.org/2005/Atom"/>
|
||||
</except>
|
||||
</anyName>
|
||||
<text/>
|
||||
</element>
|
||||
</define>
|
||||
<!-- Structured Extension -->
|
||||
<define name="structuredExtensionElement">
|
||||
<element>
|
||||
<anyName>
|
||||
<except>
|
||||
<nsName ns="http://www.w3.org/2005/Atom"/>
|
||||
</except>
|
||||
</anyName>
|
||||
<choice>
|
||||
<group>
|
||||
<oneOrMore>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
</oneOrMore>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</group>
|
||||
<group>
|
||||
<zeroOrMore>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
</zeroOrMore>
|
||||
<group>
|
||||
<optional>
|
||||
<text/>
|
||||
</optional>
|
||||
<oneOrMore>
|
||||
<ref name="anyElement"/>
|
||||
</oneOrMore>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</group>
|
||||
</group>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
<!-- Other Extensibility -->
|
||||
<define name="extensionElement">
|
||||
<choice>
|
||||
<ref name="simpleExtensionElement"/>
|
||||
<ref name="structuredExtensionElement"/>
|
||||
</choice>
|
||||
</define>
|
||||
<define name="undefinedAttribute">
|
||||
<attribute>
|
||||
<anyName>
|
||||
<except>
|
||||
<name>xml:base</name>
|
||||
<name>xml:lang</name>
|
||||
<nsName ns=""/>
|
||||
</except>
|
||||
</anyName>
|
||||
</attribute>
|
||||
</define>
|
||||
<define name="undefinedContent">
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<text/>
|
||||
<ref name="anyForeignElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</define>
|
||||
<define name="anyElement">
|
||||
<element>
|
||||
<anyName/>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<define name="anyForeignElement">
|
||||
<element>
|
||||
<anyName>
|
||||
<except>
|
||||
<nsName ns="http://www.w3.org/2005/Atom"/>
|
||||
</except>
|
||||
</anyName>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<!-- XHTML -->
|
||||
<define name="anyXHTML">
|
||||
<element>
|
||||
<nsName/>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="anyXHTML"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<define name="xhtmlDiv">
|
||||
<element name="xhtml:div">
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="anyXHTML"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
</grammar>
|
||||
<!-- EOF -->
|
BIN
test/jing.jar
Normal file
BIN
test/jing.jar
Normal file
Binary file not shown.
599
test/opds_catalog_1_1.rng
Normal file
599
test/opds_catalog_1_1.rng
Normal file
|
@ -0,0 +1,599 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
-*- rnc -*-
|
||||
RELAX NG Compact Syntax Grammar for OPDS Catalog Feed & Entry Documents
|
||||
Version 2010-08-18
|
||||
-->
|
||||
<grammar xmlns:atom="http://www.w3.org/2005/Atom" xmlns:opds="http://opds-spec.org/2010/catalog" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
<!--
|
||||
The OPDS Catalog spec extends Atom (RFC4287), and the additions require some
|
||||
patterns not used in the Atom schema. The first is atomUriExceptOPDS, which
|
||||
is used to describe an atomLink whose rel value is an atomNCName (no-colon
|
||||
name) or any URI other than these from OPDS Catalogs. In these cases, no
|
||||
opds:price element should appear.
|
||||
-->
|
||||
<define name="atomUriExceptOPDS">
|
||||
<data type="string" datatypeLibrary="">
|
||||
<except>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/buy</value>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/borrow</value>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/subscribe</value>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/sample</value>
|
||||
</except>
|
||||
</data>
|
||||
</define>
|
||||
<!--
|
||||
Next is OPDSUrisExceptBuy, which is used to describe an atomLink whose
|
||||
rel value is from OPDS Catalogs but is not ".../acquisition/buy". In such
|
||||
cases, an opds:price element is optional.
|
||||
-->
|
||||
<define name="OPDSUrisExceptBuy">
|
||||
<choice>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/borrow</value>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/subscribe</value>
|
||||
<value type="string" datatypeLibrary="">http://opds-spec.org/acquisition/sample</value>
|
||||
</choice>
|
||||
</define>
|
||||
<!--
|
||||
To simplify OPDS Catalog validation, we do not use Schematron to assert that
|
||||
any atom:link with a rel value of ".../acquisition/buy" must be accompanied
|
||||
by one or more opds:price elements.
|
||||
Instead we rely on Relax NG to describe one of three situations:
|
||||
- the rel value is ".../acquisition/buy" and at least one opds:price element
|
||||
is required
|
||||
- the rel value is ".../acquisition/borrow" or ".../acquisition/subscribe" or
|
||||
".../acquisition/sample", in case opds:price elements may be
|
||||
included; or
|
||||
- the value of the rel attribute is any other URI or an Atom-defined no-colon
|
||||
name, and no opds:price element is permitted
|
||||
-->
|
||||
<!--
|
||||
Note that this OPDS Catalog schema includes atom.rnc, so that schema must be
|
||||
present for validation.
|
||||
|
||||
Note also that atom.rnc defines atomUri as text and not as xsd:anyURI, and so
|
||||
wherever the Atom spec requires an IRI, the schema will not check the value
|
||||
against any URI pattern or logic. The OPDS Catalog schema overrides atom.rnc
|
||||
to provide a relatively accurate test. With the approval of XSD 1.1, the
|
||||
schema definition should change to xsd:anyURI to match what the spec text
|
||||
says.
|
||||
-->
|
||||
<include href="atom.rng">
|
||||
<define name="undefinedAttribute">
|
||||
<attribute>
|
||||
<anyName>
|
||||
<except>
|
||||
<name>xml:base</name>
|
||||
<name>xml:lang</name>
|
||||
<nsName ns=""/>
|
||||
<nsName ns="http://opds-spec.org/2010/catalog"/>
|
||||
</except>
|
||||
</anyName>
|
||||
</attribute>
|
||||
</define>
|
||||
<define name="atomLink">
|
||||
<element name="atom:link">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="href">
|
||||
<ref name="atomUri"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<ref name="atomMediaType"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="hreflang">
|
||||
<ref name="atomLanguageTag"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="title"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="length"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<choice>
|
||||
<group>
|
||||
<attribute name="rel">
|
||||
<value>http://opds-spec.org/facet</value>
|
||||
</attribute>
|
||||
<interleave>
|
||||
<optional>
|
||||
<attribute name="opds:facetGroup"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="opds:activeFacet">
|
||||
<value>true</value>
|
||||
</attribute>
|
||||
</optional>
|
||||
</interleave>
|
||||
</group>
|
||||
<group>
|
||||
<attribute name="rel">
|
||||
<value>http://opds-spec.org/acquisition/buy</value>
|
||||
</attribute>
|
||||
<oneOrMore>
|
||||
<ref name="opdsPrice"/>
|
||||
</oneOrMore>
|
||||
</group>
|
||||
<group>
|
||||
<attribute name="rel">
|
||||
<ref name="OPDSUrisExceptBuy"/>
|
||||
</attribute>
|
||||
<zeroOrMore>
|
||||
<ref name="opdsPrice"/>
|
||||
</zeroOrMore>
|
||||
</group>
|
||||
<attribute name="rel">
|
||||
<choice>
|
||||
<ref name="atomNCName"/>
|
||||
<ref name="atomUriExceptOPDS"/>
|
||||
</choice>
|
||||
</attribute>
|
||||
</choice>
|
||||
</optional>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<ref name="opdsIndirectAcquisition"/>
|
||||
<ref name="anyOPDSForeignElement"/>
|
||||
<text/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<!--
|
||||
Here is where OPDS Catalogs use John Cowan's pragmatic evaluation of an
|
||||
IRI. This modifies xsd:anyURI in XSD 1.0 to exclude ASCII characters not
|
||||
valid in 1.1 or IRI's without being escaped. This matches the OPDS and Atom
|
||||
specs, but not the non-normative atom.rnc.
|
||||
-->
|
||||
<define name="atomUri">
|
||||
<data type="anyURI">
|
||||
<except>
|
||||
<data type="string">
|
||||
<param name="pattern">.*[ <>{}|^`"\\\n\r\t].*</param>
|
||||
</data>
|
||||
</except>
|
||||
</data>
|
||||
</define>
|
||||
<!--
|
||||
Here we override Atom to account for HTML abuse in the summary element,
|
||||
restricting it in OPDS Catalog to text:
|
||||
-->
|
||||
<define name="atomSummary">
|
||||
<element name="atom:summary">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<value>text</value>
|
||||
</attribute>
|
||||
</optional>
|
||||
<text/>
|
||||
</element>
|
||||
</define>
|
||||
</include>
|
||||
<define name="anyOPDSForeignElement">
|
||||
<element>
|
||||
<anyName>
|
||||
<except>
|
||||
<nsName ns="http://www.w3.org/2005/Atom"/>
|
||||
<nsName ns="http://opds-spec.org/2010/catalog"/>
|
||||
</except>
|
||||
</anyName>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<attribute>
|
||||
<anyName/>
|
||||
</attribute>
|
||||
<text/>
|
||||
<ref name="anyElement"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<!--
|
||||
An opds:indirectAcquisition should use strictly MIME media type for
|
||||
its type attribute
|
||||
-->
|
||||
<define name="opdsIndirectAcquisition">
|
||||
<element name="opds:indirectAcquisition">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="type">
|
||||
<ref name="atomMediaType"/>
|
||||
</attribute>
|
||||
<zeroOrMore>
|
||||
<choice>
|
||||
<ref name="anyOPDSForeignElement"/>
|
||||
<ref name="opdsIndirectAcquisition"/>
|
||||
</choice>
|
||||
</zeroOrMore>
|
||||
</element>
|
||||
</define>
|
||||
<!--
|
||||
An opds:price element should not contain a currency symbol; it is
|
||||
restricted to non-negative decimal numbers.
|
||||
-->
|
||||
<define name="opdsPrice">
|
||||
<element name="opds:price">
|
||||
<ref name="atomCommonAttributes"/>
|
||||
<attribute name="currencycode">
|
||||
<ref name="opdsPriceCurrencyCode"/>
|
||||
</attribute>
|
||||
<data type="decimal">
|
||||
<param name="minInclusive">0.0</param>
|
||||
</data>
|
||||
</element>
|
||||
</define>
|
||||
<!--
|
||||
Instead of allowing every possible 3-letter or 3-digit combination as a
|
||||
currency code, here the permissible codes (as identified in ISO4217 as of
|
||||
2010-08-25) are enumerated. In 2012 or so, that standard may add, remove or
|
||||
change some currency codes, thus requiring this schema to be updated. Note
|
||||
that codes for metals and funds are not included.
|
||||
-->
|
||||
<define name="opdsPriceCurrencyCode">
|
||||
<choice>
|
||||
<value>AED</value>
|
||||
<value>AFN</value>
|
||||
<value>ALL</value>
|
||||
<value>AMD</value>
|
||||
<value>ANG</value>
|
||||
<value>AOA</value>
|
||||
<value>ARS</value>
|
||||
<value>AUD</value>
|
||||
<value>AWG</value>
|
||||
<value>AZN</value>
|
||||
<value>BAM</value>
|
||||
<value>BBD</value>
|
||||
<value>BDT</value>
|
||||
<value>BGN</value>
|
||||
<value>BHD</value>
|
||||
<value>BIF</value>
|
||||
<value>BMD</value>
|
||||
<value>BND</value>
|
||||
<value>BOB</value>
|
||||
<value>BOV</value>
|
||||
<value>BRL</value>
|
||||
<value>BSD</value>
|
||||
<value>BTN</value>
|
||||
<value>BWP</value>
|
||||
<value>BYR</value>
|
||||
<value>BZD</value>
|
||||
<value>CAD</value>
|
||||
<value>CDF</value>
|
||||
<value>CHE</value>
|
||||
<value>CHF</value>
|
||||
<value>CHW</value>
|
||||
<value>CLF</value>
|
||||
<value>CLP</value>
|
||||
<value>CNY</value>
|
||||
<value>COP</value>
|
||||
<value>COU</value>
|
||||
<value>CRC</value>
|
||||
<value>CUC</value>
|
||||
<value>CUP</value>
|
||||
<value>CVE</value>
|
||||
<value>CZK</value>
|
||||
<value>DJF</value>
|
||||
<value>DKK</value>
|
||||
<value>DOP</value>
|
||||
<value>DZD</value>
|
||||
<value>EEK</value>
|
||||
<value>EGP</value>
|
||||
<value>ERN</value>
|
||||
<value>ETB</value>
|
||||
<value>EUR</value>
|
||||
<value>FJD</value>
|
||||
<value>FKP</value>
|
||||
<value>GBP</value>
|
||||
<value>GEL</value>
|
||||
<value>GHS</value>
|
||||
<value>GIP</value>
|
||||
<value>GMD</value>
|
||||
<value>GNF</value>
|
||||
<value>GTQ</value>
|
||||
<value>GYD</value>
|
||||
<value>HKD</value>
|
||||
<value>HNL</value>
|
||||
<value>HRK</value>
|
||||
<value>HTG</value>
|
||||
<value>HUF</value>
|
||||
<value>IDR</value>
|
||||
<value>ILS</value>
|
||||
<value>INR</value>
|
||||
<value>IQD</value>
|
||||
<value>IRR</value>
|
||||
<value>ISK</value>
|
||||
<value>JMD</value>
|
||||
<value>JOD</value>
|
||||
<value>JPY</value>
|
||||
<value>KES</value>
|
||||
<value>KGS</value>
|
||||
<value>KHR</value>
|
||||
<value>KMF</value>
|
||||
<value>KPW</value>
|
||||
<value>KRW</value>
|
||||
<value>KWD</value>
|
||||
<value>KYD</value>
|
||||
<value>KZT</value>
|
||||
<value>LAK</value>
|
||||
<value>LBP</value>
|
||||
<value>LKR</value>
|
||||
<value>LRD</value>
|
||||
<value>LSL</value>
|
||||
<value>LTL</value>
|
||||
<value>LVL</value>
|
||||
<value>LYD</value>
|
||||
<value>MAD</value>
|
||||
<value>MDL</value>
|
||||
<value>MGA</value>
|
||||
<value>MKD</value>
|
||||
<value>MMK</value>
|
||||
<value>MNT</value>
|
||||
<value>MOP</value>
|
||||
<value>MRO</value>
|
||||
<value>MUR</value>
|
||||
<value>MVR</value>
|
||||
<value>MWK</value>
|
||||
<value>MXN</value>
|
||||
<value>MXV</value>
|
||||
<value>MYR</value>
|
||||
<value>MZN</value>
|
||||
<value>NAD</value>
|
||||
<value>NGN</value>
|
||||
<value>NIO</value>
|
||||
<value>NOK</value>
|
||||
<value>NPR</value>
|
||||
<value>NZD</value>
|
||||
<value>OMR</value>
|
||||
<value>PAB</value>
|
||||
<value>PEN</value>
|
||||
<value>PGK</value>
|
||||
<value>PHP</value>
|
||||
<value>PKR</value>
|
||||
<value>PLN</value>
|
||||
<value>PYG</value>
|
||||
<value>QAR</value>
|
||||
<value>RON</value>
|
||||
<value>RSD</value>
|
||||
<value>RUB</value>
|
||||
<value>RWF</value>
|
||||
<value>SAR</value>
|
||||
<value>SBD</value>
|
||||
<value>SCR</value>
|
||||
<value>SDG</value>
|
||||
<value>SEK</value>
|
||||
<value>SGD</value>
|
||||
<value>SHP</value>
|
||||
<value>SLL</value>
|
||||
<value>SOS</value>
|
||||
<value>SRD</value>
|
||||
<value>STD</value>
|
||||
<value>SVC</value>
|
||||
<value>SYP</value>
|
||||
<value>SZL</value>
|
||||
<value>THB</value>
|
||||
<value>TJS</value>
|
||||
<value>TMT</value>
|
||||
<value>TND</value>
|
||||
<value>TOP</value>
|
||||
<value>TRY</value>
|
||||
<value>TTD</value>
|
||||
<value>TWD</value>
|
||||
<value>TZS</value>
|
||||
<value>UAH</value>
|
||||
<value>UGX</value>
|
||||
<value>USD</value>
|
||||
<value>USN</value>
|
||||
<value>USS</value>
|
||||
<value>UYI</value>
|
||||
<value>UYU</value>
|
||||
<value>UZS</value>
|
||||
<value>VEF</value>
|
||||
<value>VND</value>
|
||||
<value>VUV</value>
|
||||
<value>WST</value>
|
||||
<value>XAF</value>
|
||||
<value>XAG</value>
|
||||
<value>XAU</value>
|
||||
<value>XBA</value>
|
||||
<value>XBB</value>
|
||||
<value>XBC</value>
|
||||
<value>XBD</value>
|
||||
<value>XCD</value>
|
||||
<value>XDR</value>
|
||||
<value>XFU</value>
|
||||
<value>XOF</value>
|
||||
<value>XPD</value>
|
||||
<value>XPF</value>
|
||||
<value>XPT</value>
|
||||
<value>XTS</value>
|
||||
<value>XXX</value>
|
||||
<value>YER</value>
|
||||
<value>ZAR</value>
|
||||
<value>ZMK</value>
|
||||
<value>ZWL</value>
|
||||
<value>008</value>
|
||||
<value>012</value>
|
||||
<value>032</value>
|
||||
<value>036</value>
|
||||
<value>044</value>
|
||||
<value>048</value>
|
||||
<value>050</value>
|
||||
<value>051</value>
|
||||
<value>052</value>
|
||||
<value>060</value>
|
||||
<value>064</value>
|
||||
<value>068</value>
|
||||
<value>072</value>
|
||||
<value>084</value>
|
||||
<value>090</value>
|
||||
<value>096</value>
|
||||
<value>104</value>
|
||||
<value>108</value>
|
||||
<value>116</value>
|
||||
<value>124</value>
|
||||
<value>132</value>
|
||||
<value>136</value>
|
||||
<value>144</value>
|
||||
<value>152</value>
|
||||
<value>156</value>
|
||||
<value>170</value>
|
||||
<value>174</value>
|
||||
<value>188</value>
|
||||
<value>191</value>
|
||||
<value>192</value>
|
||||
<value>203</value>
|
||||
<value>208</value>
|
||||
<value>214</value>
|
||||
<value>222</value>
|
||||
<value>230</value>
|
||||
<value>232</value>
|
||||
<value>233</value>
|
||||
<value>238</value>
|
||||
<value>242</value>
|
||||
<value>262</value>
|
||||
<value>270</value>
|
||||
<value>292</value>
|
||||
<value>320</value>
|
||||
<value>324</value>
|
||||
<value>328</value>
|
||||
<value>332</value>
|
||||
<value>340</value>
|
||||
<value>344</value>
|
||||
<value>348</value>
|
||||
<value>352</value>
|
||||
<value>356</value>
|
||||
<value>360</value>
|
||||
<value>364</value>
|
||||
<value>368</value>
|
||||
<value>376</value>
|
||||
<value>388</value>
|
||||
<value>392</value>
|
||||
<value>398</value>
|
||||
<value>400</value>
|
||||
<value>404</value>
|
||||
<value>408</value>
|
||||
<value>410</value>
|
||||
<value>414</value>
|
||||
<value>417</value>
|
||||
<value>418</value>
|
||||
<value>422</value>
|
||||
<value>426</value>
|
||||
<value>428</value>
|
||||
<value>430</value>
|
||||
<value>434</value>
|
||||
<value>440</value>
|
||||
<value>446</value>
|
||||
<value>454</value>
|
||||
<value>458</value>
|
||||
<value>462</value>
|
||||
<value>478</value>
|
||||
<value>480</value>
|
||||
<value>484</value>
|
||||
<value>496</value>
|
||||
<value>498</value>
|
||||
<value>504</value>
|
||||
<value>512</value>
|
||||
<value>516</value>
|
||||
<value>524</value>
|
||||
<value>532</value>
|
||||
<value>533</value>
|
||||
<value>548</value>
|
||||
<value>554</value>
|
||||
<value>558</value>
|
||||
<value>566</value>
|
||||
<value>578</value>
|
||||
<value>586</value>
|
||||
<value>590</value>
|
||||
<value>598</value>
|
||||
<value>600</value>
|
||||
<value>604</value>
|
||||
<value>608</value>
|
||||
<value>634</value>
|
||||
<value>643</value>
|
||||
<value>646</value>
|
||||
<value>654</value>
|
||||
<value>678</value>
|
||||
<value>682</value>
|
||||
<value>690</value>
|
||||
<value>694</value>
|
||||
<value>702</value>
|
||||
<value>704</value>
|
||||
<value>706</value>
|
||||
<value>710</value>
|
||||
<value>748</value>
|
||||
<value>752</value>
|
||||
<value>756</value>
|
||||
<value>760</value>
|
||||
<value>764</value>
|
||||
<value>776</value>
|
||||
<value>780</value>
|
||||
<value>784</value>
|
||||
<value>788</value>
|
||||
<value>800</value>
|
||||
<value>807</value>
|
||||
<value>818</value>
|
||||
<value>826</value>
|
||||
<value>834</value>
|
||||
<value>840</value>
|
||||
<value>858</value>
|
||||
<value>860</value>
|
||||
<value>882</value>
|
||||
<value>886</value>
|
||||
<value>894</value>
|
||||
<value>901</value>
|
||||
<value>931</value>
|
||||
<value>932</value>
|
||||
<value>934</value>
|
||||
<value>936</value>
|
||||
<value>937</value>
|
||||
<value>938</value>
|
||||
<value>940</value>
|
||||
<value>941</value>
|
||||
<value>943</value>
|
||||
<value>944</value>
|
||||
<value>946</value>
|
||||
<value>947</value>
|
||||
<value>948</value>
|
||||
<value>949</value>
|
||||
<value>950</value>
|
||||
<value>951</value>
|
||||
<value>952</value>
|
||||
<value>953</value>
|
||||
<value>955</value>
|
||||
<value>956</value>
|
||||
<value>957</value>
|
||||
<value>958</value>
|
||||
<value>959</value>
|
||||
<value>960</value>
|
||||
<value>961</value>
|
||||
<value>962</value>
|
||||
<value>963</value>
|
||||
<value>964</value>
|
||||
<value>968</value>
|
||||
<value>969</value>
|
||||
<value>970</value>
|
||||
<value>971</value>
|
||||
<value>972</value>
|
||||
<value>973</value>
|
||||
<value>974</value>
|
||||
<value>975</value>
|
||||
<value>976</value>
|
||||
<value>977</value>
|
||||
<value>978</value>
|
||||
<value>979</value>
|
||||
<value>980</value>
|
||||
<value>981</value>
|
||||
<value>984</value>
|
||||
<value>985</value>
|
||||
<value>986</value>
|
||||
<value>990</value>
|
||||
<value>997</value>
|
||||
<value>998</value>
|
||||
<value>999</value>
|
||||
</choice>
|
||||
</define>
|
||||
</grammar>
|
Loading…
Reference in a new issue