aboutsummaryrefslogtreecommitdiff
path: root/cnf
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2016-04-17 10:06:29 +0200
committerBrian Dolbec <dolsen@gentoo.org>2016-04-25 08:28:53 -0700
commit275ac5e04bb296394c308bdd6dfd92ac51cfbd42 (patch)
treecb0c166b920eec65e4114d31c404b714f1c511d7 /cnf
parentrepoman: Use XML Schema for metadata.xml validation (diff)
downloadportage-275ac5e04bb296394c308bdd6dfd92ac51cfbd42.tar.gz
portage-275ac5e04bb296394c308bdd6dfd92ac51cfbd42.tar.bz2
portage-275ac5e04bb296394c308bdd6dfd92ac51cfbd42.zip
tests: Include metadata.xsd for repoman tests
Diffstat (limited to 'cnf')
-rw-r--r--cnf/metadata.dtd102
-rw-r--r--cnf/metadata.xsd547
2 files changed, 547 insertions, 102 deletions
diff --git a/cnf/metadata.dtd b/cnf/metadata.dtd
deleted file mode 100644
index ff2649cad..000000000
--- a/cnf/metadata.dtd
+++ /dev/null
@@ -1,102 +0,0 @@
-<!ELEMENT packages ( pkgmetadata* )>
-
-<!-- Metadata for a category -->
-<!ELEMENT catmetadata ( (longdescription)* )>
-<!ATTLIST catmetadata pkgname CDATA "">
-
-<!-- Metadata for a package -->
-<!ELEMENT pkgmetadata ( (herd|maintainer|natural-name|longdescription|use|upstream)* )>
-<!ATTLIST pkgmetadata pkgname CDATA "">
-
- <!-- One tag for each herd this package is assigned to. -->
- <!ELEMENT herd (#PCDATA)>
-
- <!-- One tag for each maintainer of a package, multiple allowed-->
- <!ELEMENT maintainer ( email, (description| name)* )>
-
- <!-- Natural name for package, example: LibreOffice (for app-office/libreoffice) -->
- <!ELEMENT natural-name (#PCDATA) >
-
- <!-- A long description of the package in freetext-->
- <!ELEMENT longdescription (#PCDATA|pkg|cat)* >
-
- <!-- The changelog of the package-->
- <!-- Please note that #PCDATA is mentioned only for the upstream changelog
- element, where the content is a URL. This is due to limitations of the DTD -->
- <!ELEMENT changelog (#PCDATA|change)* >
- <!-- The changelog contains various "changes"-->
- <!ELEMENT change (date,(developer|version|description|file|contributor|bug)*) >
- <!ELEMENT date (#PCDATA) >
- <!-- The date of the change, in "YYYY-MM-DD" format -->
- <!ELEMENT developer (name?,email) >
- <!-- The developer that made the change. The email is required, name
- is optional-->
- <!ELEMENT version (#PCDATA) >
- <!--version of the packages involved (one tag per version)-->
- <!ELEMENT file (#PCDATA) ><!-- one tag per file touched -->
- <!ELEMENT contributor (name?,email?) >
- <!-- A reference to a user that helped in causing this change.
- There should at least be a name or email address included.
- Email is preferred -->
- <!ELEMENT bug (#PCDATA) >
- <!-- bug-id of a bug fixed by this change, multiple allowed. The
- format of this is a number or alias for a bug. NOT including a
- # character -->
-
- <!-- description of what this USE flag does for this package -->
- <!ELEMENT use (flag)* >
- <!ELEMENT flag (#PCDATA|pkg|cat)* >
- <!-- name attribute holds the name of the USE flag -->
- <!ATTLIST flag name CDATA #REQUIRED >
-
- <!-- upstream metadata information (maintainers, upstream docs,..) -->
- <!ELEMENT upstream (maintainer|changelog|doc|bugs-to|remote-id)* >
- <!-- Due to the limitation of DTD this will also allow a status
- attribute for the package maintainer element. Please note that
- the usage of the status attribute is nevertheless _only_ allowed
- in the upstream maintainer element. -->
- <!ATTLIST maintainer status (active|inactive|unknown) "unknown" >
- <!-- URL where the location of the upstream documentation can be found -->
- <!ELEMENT doc (#PCDATA)>
- <!ATTLIST doc lang CDATA "C" >
- <!-- location where to report bugs
- (may also be an email address prefixed with mailto:) -->
- <!ELEMENT bugs-to (#PCDATA)>
- <!-- specify a type of package identification tracker -->
- <!ELEMENT remote-id (#PCDATA)>
- <!ATTLIST remote-id type (bitbucket|cpan|cpan-module|cpe|cran|ctan|freecode|freshmeat|github|gitorious|google-code|launchpad|pear|pecl|pypi|rubyforge|rubygems|sourceforge|sourceforge-jp|vim) #REQUIRED>
-
- <!-- category/package information for cross-linking in descriptions
- and useflag descriptions -->
- <!ELEMENT pkg (#PCDATA) >
- <!ELEMENT cat (#PCDATA) >
-
-<!-- Common attributes -->
-
-<!-- the lang attribute, specifies the language of this tag. This is
- only useful for descriptions of various kinds. If a tag with this
- attribute is included there must be a description in the default
- language "C" or "en", which is equivalent -->
- <!ATTLIST description lang CDATA "C" >
- <!ATTLIST longdescription lang CDATA "C" >
- <!ATTLIST use lang CDATA "C" >
-
-<!-- The restrict attribute, this attribute specifies restrictions on
- the applicability of tags on versions. The format of this attribute is
- equal to the format of DEPEND lines in ebuilds. There is one special
- value though: restrict="*". A tag that specifies this only applies if
- there are no other tags that apply.
-
- For required tags, there must be either an unrestricted version, or a
- version that is default restricted. -->
- <!ATTLIST herd restrict CDATA #IMPLIED >
- <!ATTLIST maintainer restrict CDATA #IMPLIED >
- <!ATTLIST longdescription restrict CDATA #IMPLIED >
- <!ATTLIST flag restrict CDATA #IMPLIED >
-
-
-
-<!-- standard parts -->
-<!ELEMENT email (#PCDATA) ><!-- an email address -->
-<!ELEMENT name (#PCDATA) ><!-- the name of a person (maintainer, contributor)-->
-<!ELEMENT description (#PCDATA) ><!-- A description of a maintainer or change-->
diff --git a/cnf/metadata.xsd b/cnf/metadata.xsd
new file mode 100644
index 000000000..0ead09ee8
--- /dev/null
+++ b/cnf/metadata.xsd
@@ -0,0 +1,547 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
+ <!-- top-level variants -->
+ <xs:element name='pkgmetadata' type='pkgMetadataType'>
+ <!-- note: restrict uniquity rules are simplified
+ the spec says: one for each matched package
+ we can only do: one for each restrict rule -->
+ <xs:unique name='longDescUniquityConstraint'>
+ <xs:selector xpath='longdescription'/>
+ <xs:field xpath='@lang'/>
+ <xs:field xpath='@restrict'/>
+ </xs:unique>
+ <xs:unique name='maintainerUniquityConstraint'>
+ <xs:selector xpath='maintainer'/>
+ <xs:field xpath='email'/>
+ <xs:field xpath='@restrict'/>
+ </xs:unique>
+ <xs:unique name='slotsUniquityConstraint'>
+ <xs:selector xpath='slots'/>
+ <xs:field xpath='@lang'/>
+ </xs:unique>
+ <xs:unique name='upstreamSingleConstraint'>
+ <xs:selector xpath='upstream'/>
+ <xs:field xpath='@fake-only-once'/>
+ </xs:unique>
+ <xs:unique name='useUniquityConstraint'>
+ <xs:selector xpath='use'/>
+ <xs:field xpath='@lang'/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name='catmetadata' type='catMetadataType'>
+ <xs:unique name='catLongDescUniquityConstraint'>
+ <xs:selector xpath='longdescription'/>
+ <xs:field xpath='@lang'/>
+ </xs:unique>
+ </xs:element>
+
+ <!-- global elements -->
+ <xs:complexType name='pkgMetadataType'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='longdescription' type='longDescType'/>
+ <xs:element name='maintainer' type='maintainerType'>
+ <xs:unique name='maintainerDescUniquityConstraint'>
+ <xs:selector xpath='description'/>
+ <xs:field xpath='@lang'/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name='slots' type='slotsType'>
+ <xs:unique name='slotUniquityConstraint'>
+ <xs:selector xpath='slot'/>
+ <xs:field xpath='@name'/>
+ </xs:unique>
+ <xs:unique name='subslotsSingleConstraint'>
+ <xs:selector xpath='subslots'/>
+ <xs:field xpath='@fake-only-once'/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name='upstream' type='upstreamType'>
+ <xs:unique name='bugsToSingleConstraint'>
+ <xs:selector xpath='bugs-to'/>
+ <xs:field xpath='@fake-only-once'/>
+ </xs:unique>
+ <xs:unique name='changelogSingleConstraint'>
+ <xs:selector xpath='changelog'/>
+ <xs:field xpath='@fake-only-once'/>
+ </xs:unique>
+ <!-- prevent accidentally repeating the same remote -->
+ <xs:unique name='upstreamRemoteIdRepetitionConstraint'>
+ <xs:selector xpath='remote-id'/>
+ <xs:field xpath='@type'/>
+ <xs:field xpath='.'/>
+ </xs:unique>
+ <xs:unique name='upstreamDocUniquityConstraint'>
+ <xs:selector xpath='doc'/>
+ <xs:field xpath='@lang'/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name='use' type='useType'>
+ <xs:unique name='flagUniquityConstraint'>
+ <xs:selector xpath='flag'/>
+ <xs:field xpath='@name'/>
+ <xs:field xpath='@restrict'/>
+ </xs:unique>
+ </xs:element>
+ </xs:choice>
+ </xs:complexType>
+
+ <xs:complexType name='catMetadataType'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='longdescription' type='catLongDescType'/>
+ </xs:choice>
+ </xs:complexType>
+
+ <!-- the huge <upstream/> structure -->
+ <xs:complexType name='upstreamType'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='maintainer' type='upstreamMaintainerType'>
+ <xs:unique name='upstreamMaintainerUniquityConstraint'>
+ <xs:selector xpath='maintainer'/>
+ <xs:field xpath='name'/>
+ </xs:unique>
+ </xs:element>
+ <xs:element name='changelog' type='urlOnceType'/>
+ <xs:element name='doc' type='upstreamDocType'/>
+ <xs:element name='bugs-to' type='urlOnceType'/>
+ <xs:element name='remote-id' type='upstreamRemoteIdType'/>
+ </xs:choice>
+ <xs:attribute name='fake-only-once'
+ fixed='there can be at most one &lt;upstream/&gt; element'/>
+ </xs:complexType>
+
+ <!-- maintainer in two variants -->
+ <xs:complexType name='maintainerType'>
+ <xs:all>
+ <xs:element name='email' type='emailType'
+ minOccurs='1'/>
+ <xs:element name='name' type='xs:token'
+ minOccurs='0'/>
+ <xs:element name='description' type='maintainerDescType'
+ minOccurs='0'/>
+ </xs:all>
+ <xs:attribute name='type' type='maintainerTypeAttrType'
+ use='required'/>
+ <xs:attribute name='restrict' type='restrictAttrType'/>
+ </xs:complexType>
+
+ <xs:simpleType name='maintainerTypeAttrType'>
+ <xs:restriction base='xs:token'>
+ <xs:enumeration value='person'/>
+ <xs:enumeration value='project'/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name='upstreamMaintainerType'>
+ <xs:all>
+ <xs:element name='email' type='emailType'
+ minOccurs='0'/>
+ <xs:element name='name' type='xs:token'
+ minOccurs='0'/>
+ </xs:all>
+ <xs:attribute name='status' type='upstreamMaintainerStatusAttrType'
+ default='unknown'/>
+ </xs:complexType>
+
+ <xs:simpleType name='upstreamMaintainerStatusAttrType'>
+ <xs:restriction base='xs:token'>
+ <xs:enumeration value='active'/>
+ <xs:enumeration value='inactive'/>
+ <xs:enumeration value='unknown'/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name='maintainerDescType'>
+ <xs:simpleContent>
+ <xs:extension base="xs:token">
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- long description -->
+ <xs:complexType name='longDescType' mixed='true'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='pkg' type='pkgType'/>
+ <xs:element name='cat' type='catType'/>
+ </xs:choice>
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ <xs:attribute name='restrict' type='restrictAttrType'/>
+ </xs:complexType>
+
+ <xs:complexType name='catLongDescType' mixed='true'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='pkg' type='pkgType'/>
+ <xs:element name='cat' type='catType'/>
+ </xs:choice>
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ </xs:complexType>
+
+ <!-- slots -->
+ <xs:complexType name='slotsType'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='slot' type='slotType'/>
+ <xs:element name='subslots' type='tokenOnceType'/>
+ </xs:choice>
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ </xs:complexType>
+
+ <xs:complexType name='slotType'>
+ <xs:simpleContent>
+ <xs:extension base="xs:token">
+ <xs:attribute name='name' type='slotNameAttrType'
+ use='required'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name='slotNameAttrType'>
+ <xs:restriction base='xs:token'>
+ <!-- PMS 3.1.3 Slot Names + special value '*' -->
+ <xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*|[*]"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- use flags -->
+ <xs:complexType name='useType'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='flag' type='flagType'/>
+ </xs:choice>
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ </xs:complexType>
+
+ <xs:complexType name='flagType' mixed='true'>
+ <xs:choice minOccurs='0' maxOccurs='unbounded'>
+ <xs:element name='cat' type='catType'/>
+ <xs:element name='pkg' type='pkgType'/>
+ </xs:choice>
+ <xs:attribute name='name' type='flagNameAttrType'
+ use='required'/>
+ <xs:attribute name='restrict' type='restrictAttrType'
+ default=''/>
+ </xs:complexType>
+
+ <xs:simpleType name='flagNameAttrType'>
+ <xs:restriction base='xs:token'>
+ <!-- PMS 3.1.4 USE Flag Names -->
+ <xs:pattern value="[A-Za-z0-9][A-Za-z0-9+_@-]*"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- upstream-specific types -->
+ <xs:complexType name='upstreamDocType'>
+ <xs:simpleContent>
+ <xs:extension base="urlType">
+ <xs:attribute name='lang' type='langAttrType' default='en'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name='upstreamRemoteIdType'>
+ <xs:simpleContent>
+ <xs:extension base="xs:token">
+ <xs:attribute name='type' type='upstreamRemoteIdTypeAttrType'
+ use='required'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name='upstreamRemoteIdTypeAttrType'>
+ <xs:restriction base='xs:token'>
+ <xs:enumeration value='bitbucket'/>
+ <xs:enumeration value='cpan'/>
+ <xs:enumeration value='cpan-module'/>
+ <xs:enumeration value='cpe'/>
+ <xs:enumeration value='cran'/>
+ <xs:enumeration value='ctan'/>
+ <xs:enumeration value='freecode'/>
+ <xs:enumeration value='freshmeat'/>
+ <xs:enumeration value='github'/>
+ <xs:enumeration value='gitlab'/>
+ <xs:enumeration value='gitorious'/>
+ <xs:enumeration value='google-code'/>
+ <xs:enumeration value='launchpad'/>
+ <xs:enumeration value='pear'/>
+ <xs:enumeration value='pecl'/>
+ <xs:enumeration value='pypi'/>
+ <xs:enumeration value='rubyforge'/>
+ <xs:enumeration value='rubygems'/>
+ <xs:enumeration value='sourceforge'/>
+ <xs:enumeration value='sourceforge-jp'/>
+ <xs:enumeration value='vim'/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- creepy mixed-text types -->
+ <xs:simpleType name='catType'>
+ <xs:restriction base='xs:token'>
+ <!-- PMS 3.1.1 Category Names -->
+ <xs:pattern value="[A-Za-z0-9_][A-Za-z0-9+_.-]*"/>
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:simpleType name='pkgType'>
+ <xs:restriction base='xs:token'>
+ <!-- PMS 3.1.1 Category Names + 3.1.2 Package Names -->
+ <!-- note: this does not enforce the 'anything matching
+ the version syntax' requirement -->
+ <xs:pattern
+ value="[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- common attributes -->
+ <xs:simpleType name='langAttrType'>
+ <xs:restriction base='xs:token'>
+ <!-- ISO 639-1 language codes -->
+ <xs:enumeration value='aa'/>
+ <xs:enumeration value='ab'/>
+ <xs:enumeration value='ae'/>
+ <xs:enumeration value='af'/>
+ <xs:enumeration value='ak'/>
+ <xs:enumeration value='am'/>
+ <xs:enumeration value='an'/>
+ <xs:enumeration value='ar'/>
+ <xs:enumeration value='as'/>
+ <xs:enumeration value='av'/>
+ <xs:enumeration value='ay'/>
+ <xs:enumeration value='az'/>
+ <xs:enumeration value='ba'/>
+ <xs:enumeration value='be'/>
+ <xs:enumeration value='bg'/>
+ <xs:enumeration value='bh'/>
+ <xs:enumeration value='bi'/>
+ <xs:enumeration value='bm'/>
+ <xs:enumeration value='bn'/>
+ <xs:enumeration value='bo'/>
+ <xs:enumeration value='bo'/>
+ <xs:enumeration value='br'/>
+ <xs:enumeration value='bs'/>
+ <xs:enumeration value='ca'/>
+ <xs:enumeration value='ce'/>
+ <xs:enumeration value='ch'/>
+ <xs:enumeration value='co'/>
+ <xs:enumeration value='cr'/>
+ <xs:enumeration value='cs'/>
+ <xs:enumeration value='cs'/>
+ <xs:enumeration value='cu'/>
+ <xs:enumeration value='cv'/>
+ <xs:enumeration value='cy'/>
+ <xs:enumeration value='cy'/>
+ <xs:enumeration value='da'/>
+ <xs:enumeration value='de'/>
+ <xs:enumeration value='de'/>
+ <xs:enumeration value='dv'/>
+ <xs:enumeration value='dz'/>
+ <xs:enumeration value='ee'/>
+ <xs:enumeration value='el'/>
+ <xs:enumeration value='el'/>
+ <xs:enumeration value='en'/>
+ <xs:enumeration value='eo'/>
+ <xs:enumeration value='es'/>
+ <xs:enumeration value='et'/>
+ <xs:enumeration value='eu'/>
+ <xs:enumeration value='eu'/>
+ <xs:enumeration value='fa'/>
+ <xs:enumeration value='fa'/>
+ <xs:enumeration value='ff'/>
+ <xs:enumeration value='fi'/>
+ <xs:enumeration value='fj'/>
+ <xs:enumeration value='fo'/>
+ <xs:enumeration value='fr'/>
+ <xs:enumeration value='fr'/>
+ <xs:enumeration value='fy'/>
+ <xs:enumeration value='ga'/>
+ <xs:enumeration value='ga'/>
+ <xs:enumeration value='Ga'/>
+ <xs:enumeration value='gd'/>
+ <xs:enumeration value='gl'/>
+ <xs:enumeration value='gn'/>
+ <xs:enumeration value='gu'/>
+ <xs:enumeration value='gv'/>
+ <xs:enumeration value='ha'/>
+ <xs:enumeration value='he'/>
+ <xs:enumeration value='hi'/>
+ <xs:enumeration value='ho'/>
+ <xs:enumeration value='hr'/>
+ <xs:enumeration value='ht'/>
+ <xs:enumeration value='hu'/>
+ <xs:enumeration value='hy'/>
+ <xs:enumeration value='hy'/>
+ <xs:enumeration value='hz'/>
+ <xs:enumeration value='ia'/>
+ <xs:enumeration value='id'/>
+ <xs:enumeration value='ie'/>
+ <xs:enumeration value='ig'/>
+ <xs:enumeration value='ii'/>
+ <xs:enumeration value='ik'/>
+ <xs:enumeration value='io'/>
+ <xs:enumeration value='is'/>
+ <xs:enumeration value='is'/>
+ <xs:enumeration value='it'/>
+ <xs:enumeration value='iu'/>
+ <xs:enumeration value='ja'/>
+ <xs:enumeration value='jv'/>
+ <xs:enumeration value='ka'/>
+ <xs:enumeration value='ka'/>
+ <xs:enumeration value='kg'/>
+ <xs:enumeration value='ki'/>
+ <xs:enumeration value='kj'/>
+ <xs:enumeration value='kk'/>
+ <xs:enumeration value='kl'/>
+ <xs:enumeration value='km'/>
+ <xs:enumeration value='kn'/>
+ <xs:enumeration value='ko'/>
+ <xs:enumeration value='kr'/>
+ <xs:enumeration value='ks'/>
+ <xs:enumeration value='ku'/>
+ <xs:enumeration value='kv'/>
+ <xs:enumeration value='kw'/>
+ <xs:enumeration value='ky'/>
+ <xs:enumeration value='la'/>
+ <xs:enumeration value='lb'/>
+ <xs:enumeration value='lg'/>
+ <xs:enumeration value='li'/>
+ <xs:enumeration value='ln'/>
+ <xs:enumeration value='lo'/>
+ <xs:enumeration value='lt'/>
+ <xs:enumeration value='lu'/>
+ <xs:enumeration value='lv'/>
+ <xs:enumeration value='mg'/>
+ <xs:enumeration value='mh'/>
+ <xs:enumeration value='mi'/>
+ <xs:enumeration value='mi'/>
+ <xs:enumeration value='mk'/>
+ <xs:enumeration value='mk'/>
+ <xs:enumeration value='ml'/>
+ <xs:enumeration value='mn'/>
+ <xs:enumeration value='mr'/>
+ <xs:enumeration value='ms'/>
+ <xs:enumeration value='ms'/>
+ <xs:enumeration value='mt'/>
+ <xs:enumeration value='my'/>
+ <xs:enumeration value='my'/>
+ <xs:enumeration value='na'/>
+ <xs:enumeration value='nb'/>
+ <xs:enumeration value='nd'/>
+ <xs:enumeration value='ne'/>
+ <xs:enumeration value='ng'/>
+ <xs:enumeration value='nl'/>
+ <xs:enumeration value='nl'/>
+ <xs:enumeration value='nn'/>
+ <xs:enumeration value='no'/>
+ <xs:enumeration value='nr'/>
+ <xs:enumeration value='nv'/>
+ <xs:enumeration value='ny'/>
+ <xs:enumeration value='oc'/>
+ <xs:enumeration value='oj'/>
+ <xs:enumeration value='om'/>
+ <xs:enumeration value='or'/>
+ <xs:enumeration value='os'/>
+ <xs:enumeration value='pa'/>
+ <xs:enumeration value='pi'/>
+ <xs:enumeration value='pl'/>
+ <xs:enumeration value='ps'/>
+ <xs:enumeration value='pt'/>
+ <xs:enumeration value='qu'/>
+ <xs:enumeration value='rm'/>
+ <xs:enumeration value='rn'/>
+ <xs:enumeration value='ro'/>
+ <xs:enumeration value='ro'/>
+ <xs:enumeration value='ru'/>
+ <xs:enumeration value='rw'/>
+ <xs:enumeration value='sa'/>
+ <xs:enumeration value='sc'/>
+ <xs:enumeration value='sd'/>
+ <xs:enumeration value='se'/>
+ <xs:enumeration value='sg'/>
+ <xs:enumeration value='si'/>
+ <xs:enumeration value='sk'/>
+ <xs:enumeration value='sk'/>
+ <xs:enumeration value='sl'/>
+ <xs:enumeration value='sm'/>
+ <xs:enumeration value='sn'/>
+ <xs:enumeration value='so'/>
+ <xs:enumeration value='sq'/>
+ <xs:enumeration value='sq'/>
+ <xs:enumeration value='sr'/>
+ <xs:enumeration value='ss'/>
+ <xs:enumeration value='st'/>
+ <xs:enumeration value='su'/>
+ <xs:enumeration value='sv'/>
+ <xs:enumeration value='sw'/>
+ <xs:enumeration value='ta'/>
+ <xs:enumeration value='te'/>
+ <xs:enumeration value='tg'/>
+ <xs:enumeration value='th'/>
+ <xs:enumeration value='ti'/>
+ <xs:enumeration value='tk'/>
+ <xs:enumeration value='tl'/>
+ <xs:enumeration value='tn'/>
+ <xs:enumeration value='to'/>
+ <xs:enumeration value='tr'/>
+ <xs:enumeration value='ts'/>
+ <xs:enumeration value='tt'/>
+ <xs:enumeration value='tw'/>
+ <xs:enumeration value='ty'/>
+ <xs:enumeration value='ug'/>
+ <xs:enumeration value='uk'/>
+ <xs:enumeration value='ur'/>
+ <xs:enumeration value='uz'/>
+ <xs:enumeration value='ve'/>
+ <xs:enumeration value='vi'/>
+ <xs:enumeration value='vo'/>
+ <xs:enumeration value='wa'/>
+ <xs:enumeration value='wo'/>
+ <xs:enumeration value='xh'/>
+ <xs:enumeration value='yi'/>
+ <xs:enumeration value='yo'/>
+ <xs:enumeration value='za'/>
+ <xs:enumeration value='zh'/>
+ <xs:enumeration value='zh'/>
+ <xs:enumeration value='zu'/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:simpleType name='restrictAttrType'>
+ <xs:restriction base='xs:token'>
+ <!-- simplified package dependency syntax -->
+ <!-- note: 'pure' package atom is technically valid too
+ but not really meaningful -->
+ <xs:pattern
+ value="(([&lt;&gt;]=?|[=~])[A-Za-z0-9_][A-Za-z0-9+_.-]*/[A-Za-z0-9_][A-Za-z0-9+_-]*-[0-9]+(\.[0-9]+)*[a-z]?((_alpha|_beta|_pre|_rc|_p)[0-9]*)*(-r[0-9]+)?\*?)?"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <!-- generic types -->
+ <xs:simpleType name='emailType'>
+ <xs:restriction base='xs:token'>
+ <!-- minimal safe regex -->
+ <xs:pattern value="[^@]+@[^.]+\..+"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name='tokenOnceType'>
+ <xs:simpleContent>
+ <xs:extension base="xs:token">
+ <xs:attribute name='fake-only-once'
+ fixed='there can be at most one element of this type'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name='urlType'>
+ <xs:restriction base='xs:token'>
+ <!-- TODO: something better? -->
+ <xs:pattern value="(mailto:[^@]+@[^.]+\..+|https?://.+)"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name='urlOnceType'>
+ <xs:simpleContent>
+ <xs:extension base="urlType">
+ <xs:attribute name='fake-only-once'
+ fixed='there can be at most one element of this type'/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+</xs:schema>