DTD | XML Schema | Relax NG | Schematron
This page contains examples of validating XML documents using DTD, XML Schema, Relax NG and Schematron
|
Table of Contents
|
Cardinality
- ?: optional
- +: one or more
- *: zero or more
- ,: ordered sequence
- |: choice
- &: unordered sequence
DTD
W3C Recommendation
http://www.w3.org/TR/REC-xml#dt-doctype
Validation
Validome: http://www.validome.org/grammar/
Attribute datatypes
- CDATA
- IDREF
- IDREFS
- ENTITY
- ENTITIES
- MNTOKEN
- NMTOKENS
- NOTATION
Attribute Keywords
- #REQUIRED
- #IMPLIED
- #FIXED 'VALUE'
Organisation
<!ELEMENT organisation (dataprovidername, description, administrators, address, website?)>
<!ATTLIST organisation organisationkey CDATA #REQUIRED>
logo ENTITY #IMPLIED>
<!ELEMENT dataprovidername (#PCDATA)>
<!ATTLIST dataprovidername abbreviation CDATA #IMPLIED>
<!ELEMENT description (#PCDATA)>
<!ELEMENT administrators (admin: administrator)+>
<!ELEMENT administrator (admin:name, admin:email, admin:telephone)>
<!ATTLIST administrator userkey ID #REQUIRED>
<!ELEMENT address (#PCDATA)>
<!ATTLIST address postcode CDATA #REQUIRED>
<!ELEMENT website (#PCDATA)>
<!-- Notation Declaration -->
<!NOTATION png SYSTEM "firefox.exe">
<!ENTITY logo SYSTEM "http://data.nbn.org.uk/logo.png" NDATA png>
NBN Exchange
<!ELEMENT dataset (administrators, publicaccess, metadata, records)>
<!-- Parameter Entity -->
<!ENTITY % accesscontentmodel "(resolution, download, attributes?, sensitive?, recorder?, validation)">
<!ELEMENT administrators (administrator)+>
<!ELEMENT aadministrator (name, email)>
<!ATTLIST administrator userkey ID #REQUIRED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT email (#PCDATA)>
<!ELEMENT publicaccess %accesscontentmodel;>
<!ELEMENT resolution (#PCDATA)>
<!ELEMENT download (#PCDATA)>
<!ELEMENT attributes (#PCDATA)>
<!ELEMENT sensitive (#PCDATA)>
<!ELEMENT recorder (#PCDATA)>
<!ELEMENT validation EMPTY>
<!ELEMENT metadata (title, description, methods, purpose, geographic, temporal, quality, additionalinformation, accessconstraints, useconstraints)>
<!ELEMENT title (#PCDATA |i)>
<!ELEMENT description (#PCDATA|i)>
<!ELEMENT methods (#PCDATA)>
<!ELEMENT purpose (#PCDATA)>
<!ELEMENT geographic (#PCDATA)>
<!ELEMENT temporal (#PCDATA)>
<!ELEMENT quality (#PCDATA)>
<!ELEMENT additionalinformation (#PCDATA)>
<!ELEMENT accessconstraints (#PCDATA)>
<!ELEMENT useconstraints (#PCDATA)>
<!ELEMENT records (record)+>
<!ELEMENT record (surveykey?, samplekey?, (vaguedate | date), (taxonversionkey | biotopekey), zeroabundance?, sensitive?, sitename?, spatialreference, recorder?, determiner?, attributes?)>
<!ATTLIST record recordkey ID #REQUIRED>
<!ELEMENT surveykey (#PCDATA)>
<!ELEMENT samplekey (#PCDATA)>
<!ELEMENT vaguedate (startdate, enddate, datetype)>
<!ELEMENT startdate (#PCDATA)>
<!ELEMENT enddate (#PCDATA)>
<!ELEMENT datetype (#PCDATA)>
<!ELEMENT date (#PCDATA)>
<!ELEMENT taxonversionkey (#PCDATA)>
<!ELEMENT biotopekey (#PCDATA)>
<!ELEMENT zeroabundance (#PCDATA)>
<!ELEMENT sensitive (#PCDATA)>
<!ELEMENT sitename (#PCDATA)>
<!ATTLIST sitename sitekey ID #IMPLIED>
<!ELEMENT spatialreference (gridreference | (east, north)>
<!ATTLIST spatialreference precision NMTOKEN #REQUIRED>
<!ATTLIST spatialreference projection (OSGB | OSNI | OSI | WGS84 | OSGB36) "OSGB" #REQUIRED>
<!ELEMENT gridreference (#PCDATA)>
<!ELEMENT north (#PCDATA)>
<!ELEMENT east (#PCDATA)>
<!ELEMENT recorder (#PCDATA)>
<!ELEMENT determiner (#PCDATA)>
<!ELEMENT attributes (attribute*)?>
<!ELEMENT attribute (#PCDATA)>
<!ATTLIST attribute fieldname NMTOKEN #REQUIRED>
<!-- General Entities -->
<!ENTITY EntityValue EntityTranlsatedValue
<!ENTITY accessconstraintextentity SYSTEM|PUBLIC '-//nbntrust//accessconstraint//EN' 'accessconstraint.txt'>
<!ENTITY useconstraintentity "The Gateway Terms and Conditions are applied to all datasets on the Gateway as a default">
Additional DTD
<!ELEMENT elementname ANY>
XML Schema
W3C Recommendation
- intro: http://www.w3.org/TR/xmlschema-0
- structures: http://www.w3.org/TR/xmlschema-1
- data types: http://www.w3.org/TR/xmlschema-2
DataTypes
string
normalizedString
Token
Language
NMTOKEN
NMTOKENS
Name
NCName
ID
IDREF
IDREFS
ENTITY
ENTITIES
Boolean: true|false|1|0
decimal
integer
NonPositiveInteger (<=0)
NegativeInteger (<0)
Long (+-92233720368547758080)
Int (+-2147483648)
short (+-32768)
byte (+-128)
nonNegativeInteger (>=0)
unsignedLong (18446744073709551615)
unsignedInt (4294967295)
unsignedShort (65535)
unsignedByte (255)
positiveInteger (>0)
float
double
duration: PnYnMnDTnHnMnS
dateTime: YYYY-MM-DDThh:mm:ss
time: hh:mm:ss.sss
date: YYYY-MM-DD
gYearMonth: YYYY-MM
gYear: YYYY
gMonthDay: --MM-DD
gDay: ---DD
gMonth: --MM
hexBinary
base64Binary
anyURI
QName
NOTATION
Organisation
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/organisation'
xmlns='http://data.nbn.org.uk/organisation'
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='organisation'>
<xs:annotation>
<xs:appinfo source='http://data.nbn.org.uk/organisation'/>
<xs:documentation>Organisation details</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='dataprovidername'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='abbreviation' type='xs:token' use='optional'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- ATOMIC SIMPLE TYPE -->
<xs:element name='description' type='xs:string'/>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='administrators'>
<xs:complexType>
<xs:element name='administrator' maxOccurs='unbound'/>
<xs:complexType>
<xs:sequence>
<xs:element name='name' type='xs:string'/>
<xs:element name='email' type='xs:token'/>
<xs:element name='telephone' type='xs:positiveinteger' nillable='true' />
</xs:sequence>
<xs:attribute name='userkey' type='xs:token' use='required'/>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:complexType>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='address'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='postcode' type='xs:string' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- ATOMIC SIMPLE TYPE -->
<xs:element name='website' type='xs:string' minoccurs='0'/>
</xs:sequence>
<xs:attribute name='organisationkey' type='xs:token' use='required'/>
<xs:attribute name='logo' type='xs:token' use='optional'/>
</xs:complexType>
</xs:element>
</xs:schema>
Administrators
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/admin'
xmlns='http://data.nbn.org.uk/admin'
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<xs:element name='administrators'>
<xs:annotation>
<xs:documentation>Administrator details</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:element name='administrator' type='xs:adminGroup' maxOccurs='unbound'/>
</xs:complexType>
</xs:element>
<-- NAMED COMPLEX TYPE -->
<xs:complexType name='adminGroup'>
<xs:sequence>
<xs:element name='name' type='xs:string'/>
<xs:element name='email' type='xs:token'/>
</xs:sequence>
<xs:attribute name='userkey' type='xs:token' use='required'/>
</xs:complexType>
</xs:schema>
Public Access
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/access
xmlns='http://data.nbn.org.uk/access
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='publicaccess'>
<xs:annotation>
<xs:documentation>Public Access details</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name='resolution' type='resolutiontype' />
<xs:element name='download' type='xs:boolean'/>
<xs:element name='attributes' type='xs:boolean'/>
<xs:element name='sensitive' type='xs:boolean' fixed='false'/>
<xs:element name='recorder' type='xs:boolean'/>
<xs:element name='validation' type='xs:boolean' fixed='false'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- USER DEFINED DATATYPE WITH ENUMERATION -->
<xs:simpleType name='resolutiontype'>
<xs:restriction base='xs:token'>
<xs:enumeration value='Full'/>
<xs:enumeration value='10km'/>
<xs:enumeration value='2km'/>
<xs:enumeration value='1km'/>
<xs:enumeration value='None'/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Metadata
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/metadata'
xmlns='http://data.nbn.org.uk/metadata'
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='metadata'>
<xs:complexType>
<xs:sequence>
<xs:element name='title' type='xs:string'/>
<xs:element name='description' type='xs:string'/>
<xs:element name='methods' type='xs:string'/>
<xs:element name='purpose' type='xs:string'/>
<xs:element name='geographic' type='xs:string'/>
<xs:element name='temporal' type='xs:string'/>
<xs:element name='quality' type='xs:string'/>
<xs:element name='additionalinformation' type='xs:string' minOccurs='0' />
<xs:element name='accessconstraint' type='xs:string' default='None applied' />
<xs:element name='useconstraint' type='xs:string' default='The Gateway Terms and Conditions apply' />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
NBN Exchange
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/dataset'
xmlns='http://data.nbn.org.uk/dataset'
xmlns:admin='http://data.nbn.org.uk/admin'
xmlns:access='http://data.nbn.org.uk/access'
xmlns:meta='http://data.nbn.org.uk/metadata'
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<-- IMPORT EXTERNAL XML SCHEMA WITH DIFFERING NAMESPACE-->
<xs:import namespace='http://data.nbn.org.uk/admin'
schemaLocation='http://data.nbn.org.uk/admin' 'admin.xsd'/>
<xs:import namespace='http://data.nbn.org.uk/access'
schemaLocation='http://data.nbn.org.uk/admin' 'access.xsd'/>
<xs:import namespace='http://data.nbn.org.uk/access'
schemaLocation='http://data.nbn.org.uk/metadata' 'metadata.xsd'/>
<-- INCLUDE EXTERNAL XML SCHEMA WITH SAME NAMESPACE -->
<xs:include schemaLocation='http://data.nbn.org.uk/datatyperestrictions' />
<!-- ANONYMOUS COMPLEX TYPE -->
<xs:element name='nbnexchange'>
<xs:annotation>
<xs:appinfo source='http://data.nbn.org.uk/nbnexchangeformat'/>
<xs:documentation>NBN Exchange Format</xs:documentation>
</xs:annotation
<xs:complexType>
<xs:element name='dataset'>
<xs:complexType>
<xs:sequence>
<xs:element ref='admin:administrators'/>
<xs:element ref='access:publicaccess'/>
<xs:element ref=meta:metadata'/>
<xs:element name='records'>
<xs:complexType>
<xs:element name= 'record' maxOccurs='unbound'>
<xs:complexType>
<xs:all>
<xs:element name='surveykey' type='xs:tokenkey' minOccurs='0' />
<xs:element name='samplekey' type='xs:extendedtokenkey' minOccurs='0' />
<!-- CHOICE AND GROUP -->
<xs:choice>
<xs:element name='vaguedate'>
<xs:complexType>
<xs:group ref='vaguedategroup'/>
</xs:complexType>
</xs:element>
<xs:element name='date' type='xs:date' />
</xs:choice>
<xs:choice>
<xs:element name='taxonversionkey' type='xs:speciesdictionarykey' />
<xs:element name='biotopekey' type='xs:speciesdictionarykey' />
</xs:choice>
<xs:element name='zeroabudance' type='xs:booleantype' minOccurs='0' />
<xs:element name='sensitive' type='xs:booleantype' default='F'/>
<xs:element name='sitename'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='xs:string'>
<xs:attribute name='sitekey'>
<xs:simpleType>
<xs:union memberTypes='xs:positiveInteger' 'xs:tokenKey' />
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name='spatialreference'>
<xs:complexType>
<xs:choice>
<xs:element name='gridreference'>
<xs:complexType>
<xs:simpleContent>
<xs:extension base='token'>
<xs:attributeGroup ref='spatialreference' use='required'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element type='datum'/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name='recorder' type='xs:string' minOccurs='0' />
<xs:element name=determiner' type='xs:string' minOccurs='0' />
<xs:element name='attributes' minOccurs='0'>
<xs:complexType>
<xs:element name=attribute type='xs:text' maxOccurs='unbound' />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name='recordkey' use='required'>
<xs:simpleType>
<xs:union memberTypes='xs:positiveInteger' 'xs:tokenKey' />
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name='datasetkey' type='xs:token' use='required'/>
</xs:complexType>
</xs:complexType>
</xs:element>
</xs:schema>
User defined data types
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace='http://data.nbn.org.uk/dataset'
xmlns='http://data.nbn.org.uk/dataset'
elementFormDefault='qualified'
attributeFormDefault='unqualified'
version='1.0'
xml:lang='en-GB'>
<!-- GROUP -->
<xs:group name='vaguedategroup'>
<xs:all>
<xs:element name='startdate' type='xs:date' use='optional'/>
<xs:element name='enddate' type='xs:date' />
<!-- USER DEFINED DATATYPE WITH ENUMERATION -->
<xs:element name='datetype' >
<xs:simpleType>
<xs:restriction base='xs:token'>
<xs:enumeration value='D'/>
<xs:enumeration value='DD'/>
<xs:enumeration value='O'/>
<xs:enumeration value='OO'/>
<xs:enumeration value='Y'/>
<xs:enumeration value='YY'/>
<xs:enumeration value='-Y'/>
<xs:enumeration value='ND'/>
<xs:enumeration value='U'/>
<xs:enumeration value='P'/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:group>
<!-- RESTRICTION TYPES -->
<xs:simpleType name='speciesdictionarykey'>
<xs:restriction base='token'>
<xs:maxLength='16' />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='booleantype'>
<xs:restriction base='xs:token'>
<xs:enumeration value='T'/>
<xs:enumeration value='F'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='tokenkey'>
<xs:restriction base='xs:token'>
<xs:minLength='1'/>
<xs:maxLength='30'/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name='extendedtokenkey'>
<xs:restriction base='xs:token'>
<xs:minLength='1'/>
<xs:maxLength='50'/>
</xs:restriction>
</xs:simpleType>
<!-- NAMED COMPLEX TYPE -->
<xs:complexType name='datum'>
<xs:sequence>
<xs:element name='east' type='xs:int' />
<xs:element name='north' type='xs:int' />
</xs:sequence>
<xs:attributeGroup ref='xs:spatialreference' use='required' />
</xs:complexType>
<!-- ATTRIBUTE GROUP-->
<xs:attributeGroup name='spatialreference'>
<xs:attribute name='precision' use='required'>
<xs:simpleType>
<xs:restriction base='xs:positiveinteger'>
<xs:minInclusive='1'/>
<xs:maxInclusive='10000'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name='projection' use='required'>
<xs:simpleType>
<xs:restriction base='xs:token'>
<xs:enumeration value='OSGB'/>
<xs:enumeration value='OSNI'/>
<xs:enumeration value='OSI'/>
<xs:enumeration value='WGS84'/>
<xs:enumeration value=OSGB36'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:/attributeGroup>
<!-- RESTRICTION TYPE -->
<xs:simpleType name='text'>
<xs:restriction base='string'>
<xs:maxLength='255'/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Additional user defined data types
<!-- USER DEFINED LIST DATA TYPE -->
<xs:simpleType name ='list'>
<xs:list itemType='xs:integer'/>
</xs:simpleType>
<!-- USER DEFINED LIST UNION DATA TYPE -->
<xs:element name='ELEMENTNAME' type='UNIONLIST' />
<xs:simpleType name='UNIONLIST'>
<xs:union memberTypes='LISTTYPE1 LISTTYPE 2' />
</xs:simpleType>
<xs:simpleType name='LISTTYPE1'>
<xs:list itemType='xs:int' />
</xs:simpleType>
<xs:simpleType name='LISTTYPE2'>
<xs:list itemType='xs:string' />
</xs:simpleType>
<!-- USER DEFINED REGULAR EXPRESSION DATA TYPE-->
<xs:simpleType name ='regularexpression'>
<xs:restriction base='xs:string'>
<xs:pattern value='REGULAR EXPRESSION'/>
</xs:restriction>
</xs:simpleType>
<!-- USER DEFINED IDENTITY CONSTRAINTS -->
<xs:unique name='Uniquekey'>
<xs:selector xpath='ElementName'/>
<xs:field xpath='ConstrainedNode'/>
</xs:unique>
<xs:key name='primarykey'>
<xs:selector xpath='ElementName'/>
<xs:field xpath='primarykeyNode'/>
</xs:key>
<xs:keyref name='foreignkey' refer='primarykey'>
<xs:selector xpath='ElementName'/>
<xs:field xpath='foreignkeynode'/>
</xs:keyref>
<!-- USER DEFINED NOTATION CONSTRAINTS -->
<xs:notation name='jpeg' public='image/jpeg' system='jpgviewer.exe'/>
<xs:simpleType name='imagenotation'>
<xs:restriction base='xs:notation'>
<xs:enumeration value='jpg'/>
</xs:restriction>
</xs:simpleType>
Relax NG
OASIS Recommendation
Relax NG tools
- Oxygen: http://oxygenxml.com
- Trang: http://thaiopensource.com/relaxng/tang.html
Organisation
Compact Relax NG
default namespace = "http://data.nbn.org.uk/organisation"
namespace admin = "http://data.nbn.org.uk/admin"
start = organisation
organisation = element organisation {organisationkey, logo, dataprovidername, description, administrators, postcode, website }
administrators = element administrators {administrator}+
administrator = element administrator {name, email, telephone}
organisationkey = attribute organisationkey {text}
logo = attribute logo {text}?
dataprovidername = element dataprovidername {text}
description = element description {text}?
postcode = element postcode {text}
website = element website {text}?
name = element admin:name {text}
email = element admin:email {text}
telephone = element admin:telephone {text}
Relax NG
<r:grammar xmlns ='http://data.nbn.org.uk/organisation'
xmlns:admin='http://data.nbn.org/uk/admin'
xmlns:r='http://relaxng.org/ns/structure/1.0'
xmlns:a='http://relaxng.org/ns/compatibility/annotations/1.0'>
<r:start>
<a:documentation>Relax NG schema for organisation</a:documentation>
<r:element name='organisation'>
<r:attribute name='organisationkey' />
<r:optional>
<r:attribute name='logo' />
</r:optional>
<r:element name='administrators'>
<r:oneOrMore>
<r:element name='administrator'>
<r:ref name='adminDetails' />
</r:element>
</r:oneOrMore>
</r:element>
<r:interleave>
<r:element name='dataprovidername'>
<r:text />
<r:element>
<r:zeroOrMore>
<r:element name='description'>
<r:text />
</r:element>
</r:zeroOrMore>
<r:element name='postcode'>
<r:text />
<r:element>
<r:zeroOrMore>
<r:element name='website'>
<r:text />
</r:element>
</r:zeroOrMore>
</r:interleave>
</r:element>
<r:define name='adminDetails'>
<r:interleave>
<r:element name='admin:name'>
<r:text/>
</r:element>
<r:element name='admin:email'>
<r:text/>
</r:element>
<r:element name='admin:telephone'>
<r:text/>
</r:element>
</r:interleave>
</r:define>
<r:start>
</r:grammar>
NBN Exchange Format
Compact Relax NG
div {
# includes following relax NG files
include "admin.rnc"
include "publicaccess.rnc"
include "metadata.rnc"
}
default namespace = "http://data.nbn.org.uk/dataset"
start = nbnexchange
div {
#dataset
nbnexchange = element nbnexchange {dataset, admin:administrators, access:publicaccess, meta:metadata, records }
dataset = element dataset {datasetkey}
datasetkey = attribute datasetkey {text}
records = element records {record}+
record = element record {recordkey, surveykey, samplekey, (vaguedate | date), (taxonversionkey | biotopekey), zeroabundance, sensitive, sitename, spatialreference, recorder, determiner, attributes }
}
div {
#record
recordkey = attribute recordkey {text}
surveykey = element surveykey {text}?
samplekey = element samplekey {text}?
vaguedate = grammar {
start = vaguedate
vaguedate = element vaguedate {startdate & enddate & datetype }
startdate = element startdate {strDate}
enddate = element enddate {strDate}
datetype = element datetype {'D'|'DD'|'O'|'OO'|'Y'|'YY'|'-Y'|'ND'}
}
date = element date {text}
taxonversionkey = element taxonversionkey {text}
biotopekey = element biotopekey {text}
zeroabundance = element zeroabundance {'T'|'F'}
sensitive = element sensitive {'T'|'F'}
sitename = element sitename {sitekey, str80}
sitekey = attribute sitekey {text}
spatialreference = element spatialreference {precision & projection & coordinate}
precision = attribute precision {xsl:integer}
projection = attribute projection {'OSGB'|'OSNI'|'WGS84'|'OSGB36'}
coordinate |= element gridreference {strGR}
coordinate |= element east {text}, element north {text}
recorder = element recorder {str140}
determiner = element determiner {str140}
attributes = element attributes {attribute}
attribute = element attribute {fieldname, str255}
fieldname = attribute fieldname {text}
}
div {
#user defined datatype patterns
str80 = xsd:string {maxlength="80"}
str140 = xsd:string {maxlength="140"}
str255 = xsd:string {maxlength="255"}
strGR = xsd:string {pattern ="REGULAR EXPRESSION"}
strDate = xsd:string {pattern ="REGULAR EXPRESSION"}
}
# adminsitrators namespace
admin.rnc:
namespace admin = "http://data.nbn.org.uk/admin"
start = admin:administrators
administrators = element admin:administrators {administrator}+
administrator = element admin:administrator {userkey, name, email}
userkey = attribute {text}
name = element admin:name {text}
email = element admin:name {text}?
# public access namespace
publicaccess.rnc
namespace access = "http://data.nbn.org/ukaccess"
start = access:publicaccess
publicaccess = element access:publicaccess {resolution, download, attributes, sensitive, recorder, validation }
resolution = element access:resolution {'10km'|'2km'|'1km'|'100m'}
download = element access:download {'Y'|'N'}
attributes = element access:attributes {'Y'|'N'}
sensitive = element access:sensitive {'Y'|'N'}
recorder = element access:recorder {'Y'|'N'}
validation = element access:validation {'Y'|'N'}?
# metadata namespace
metadata.rnc:
namespace = "http://data.nbn.org.uk/metadata
start = meta:metadata
metadata = element meta:metadata {title, description, methods, purpose, geographic, temporal, quality, additionalinformation, accesscontraints,useconstraints }
title = meta:title {text}
description = meta:description {mixed {element i {text} | element b {text}? | element br {empty} | {text}*}
methods = meta:methods {text}
purpose = meta:purpose {text}
geographic = meta:geographic {text}
temporal = meta:temporal {text}
quality = meta:quality {text}
additionalinformation = meta:addtionalinformation {text}
accessconstraints = meta:accessconstraints {text}
useconstraints = meta:useconstraints {text}
Relax NG
<r:grammar xmlns ='http://data.nbn.org.uk/dataset'
xmlns:admin='http://data.nbn.org/uk/admin'
xmlns:access='http://data.nbn.org/uk/publicaccess'
xmlns:meta='http://data.nbn.org/uk/metadata'
xmlns:r='http://relaxng.org/ns/structure/1.0'
xmlns:xs='http://www.w3.org/2001/XMLSchema'>
xmlns:a='http://relaxng.org/ns/compatibility/annotations/1.0'>
<r:start>
<a:documentation>Relax NG schema for dataset</a:documentation>
<r:element name='nbnexchange'>
<r:element name='admin:admin>
<r:externalRef href='admin.rng'/>
</r:element>
<r:element name='access:publicaccess'>
<r:externalRef href='publicaccess.rng'/>
</r:element>
<r:element name='meta:metadata'>
<r:externalRef href='metadata.rng'/>
</r:element>
<r:element name='dataset'>
<r:attribute name='datasetkey' />
<r:element name='records'>
<r:oneOrMore>
<r:element name='record'>
<r:ref name='recordDetails' />
</r:element>
</r:oneOrMore>
</r:element>
</r:element>
</r:element>
<r:define name='recordDetails'>
<r:attribute name='recordkey' />
<r:interleave>
<r:optional>
<r:element name='surveykey'>
<r:text />
</r:element>
</r:optional>
<r:optional>
<r:element name='samplekey'>
<r:text />
</r:element>
</r:optional>
<r:choice>
<r:element name='vaguedate'>
<r:ref='vaguedateDetails'>
</r:element>
<r:element ='date'>
<r:text />
</r:element>
</r:choice>
<r:choice>
<r:element name='taxonversionkey'>
<r:text />
</r:element>
<r:element ='biotopekey'>
<r:text />
</r:element>
</r:choice>
<r:optional>
<r:element name='zeroabundance'>
<r:data type='xs:boolean' />
</r:element>
</r:optional>
<r:optional>
<r:element name='sensitive'>
<r:data type='xs:boolean' />
</r:element>
</r:optional>
<r:optional>
<r:element name='sitename'>
<r:optional>
<r:attribute name='sitekey' />
</r:optional>
</r:element>
</r:optional>
<r:element name='spatialreference'>
<r:ref='spatialreferenceDetails'>
</r:element>
<r:optional>
<r:element name='recorder'>
<r:text />
</r:element>
</r:optional>
<r:optional>
<r:element name='determiner'>
<r:text />
</r:element>
</r:optional>
<r:optional>
<r:element name=attributes'>
<r:zeroOrMore>
<r:element name='attribute'>
<r:attribute name='fieldname' />
</r:element>
</r:zeroOrMore>
</r:element>
</r:optional>
</r:interleave>
</r:define>
<r:define name='vaguedateDetails'>
<r:interleave>
<r:element name='startdate'>
<r:text/>
</r:element>
<r:element name='enddate'>
<r:text/>
</r:element>
<r:element name='datetype'>
<r:text/>
</r:element>
</r:interleave>
</r:define>
<r:define name='spatialreferenceDetails'>
<r:choice>
<r:element name='gridreference'>
<r:text/>
</r:element>
<r:group>
<r:element name='east'>
<r:text/>
</r:element>
<r:element name='north'>
<r:text/>
</r:element>
</r:group>
</r:choice>
<r:element name='precision'>
<r:data type='xs:unsignedshort' />
</r:element>
<r:element name='projection'>
<r:text/>
</r:element>
</r:define>
<r:start>
</r:grammar>
Additional syntax
<r:element name='LIST'>
<r:list>
<r:zeroOrMore>
<r:text/>
</r:zerOrMore>
</r:list>
</r:element>
<r:element name='EMPTY'>
<r:empty />
</r:element>
<r:element name='MIXED'>
<r:mixed>
<r:zeroOrMore>
<r:element name='b'>
<r:text/>
</r:element>
</r:zeroOrMore>
</r:mixed>
</r:element>
<r:element name='ANY'>
<r:element>
<r:anyName/>
<r:zeroOrMore>
<r:attribute>
<r:anyName/>
</r:attribute>
</r:zeroOrMore>
</r:element>
</r:element>
Schematron
<-- stylesheet used to convert schematron stylesheet for use on xml document -->
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
xmlns:axsl='http://www.w3.org/1999/XSL/TransformAlias'>
<xsl:import href='skeleton1-5.xsl' <-- metastylesheet -->
<xsl:namespace-alias stylesheet-prefix='asxl' result-prefix='xsl' />
<--override named templates in imported meta-stylesheet -->
<xsl:template name='process-message'>
<axsl:message> <-- alias message element mapped to xsl namespace in result tree -->
<xsl:apply-templates mode='text' />
</axsl:message>
</xsl:template>
</xsl:stylesheet>
<-- schematron stylesheet with rules -->
<sch:schema xmlns:sch='http://xml.ascc.net/resource/schematron'>
<sch:title>Example rules</sch:title>
<sch:pattern name='Validating Elements'>
<sch:rule context='XPATH|ELEMENT'>
<-- Check name of document element -->
<sch:report test='ELEMENTNAME'> <-- returns message if true -->
The <sch:name /> element is the document element
</sch:report>
<sch:assert test='parent::*'> <-- returns message if false -->
The <sch:name /> element is the document element
</sch:assert>
<-- check child nodes of element -->
<sch:report test='node()'>
The <sch:name /> element has child nodes
</sch:report>
<sch:report test='* or text()'>
The <sch:name /> element has child nodes containing text
</sch:report>
<sch:report test='text()[normalize-space()]'>
The <sch:name /> element has child nodes containing whitespace only text
</sch:report>
<sch:report test='string()'>
The <sch:name /> element has child nodes containing text
</sch:report'>
<sch:report test='* or comment() or processing-instruction()'>
The <sch:name /> element has comment or processing instructions child nodes
</sch:report>
<sch:report test='*'>
The <sch:name /> element has child elements
</sch:report>
<sch:assert test='CHILDELEMENTNAME'>
The <sch:name /> element does not have child elements named CHILDELEMENTNAME
</sch:assert>
<sch:assert test='count(CHILDELEMENTNAME) < NUMBER)'>
The <sch:name /> element does not contain less than NUMBER CHILDELEMENTNAME elements
</sch:assert>
<sch:report test='*[not(self::CHILDELEMENTNAME1 or self::CHILDELEMENTNAME2]'>
The <sch:name /> element contains child elements other than CHILDELEMENTNAME 1 AND 2
</sch:report>
<sch:report test='*[namespace-uri()]'>
The <sch:name /> element contains child elements in a namespace
</sch:report>
<sch:report test='XMLNS:*[not(XMLNS:CHILDELEMENTNAME)]'>
The <sch:name /> element contains child elements in a XMLNS namespace which are not CHILDELEMENTNAME
</sch:report>
<sch:assert test='*[1][self::CHILDELEMENTNAME)]'>
The <sch:name /> element has first child element named CHILDELEMENTNAME
</sch:assert>
<sch:assert test='*[1][self::CHILDELEMENTNAME)]'>
The <sch:name /> element does not have a first child element named CHILDELEMENTNAME
</sch:assert>
<sch:assert test='CHILDELEMENTNAME1/following-sibling::*[1][self::CHILDELEMENTNAME2)]>
The <sch:name /> element does not have CHILDELEMENTNAME2 following CHILDELEMENTNAME1
</sch:assert>
<sch:assert test='CHILDELEMENTNAME1/preceding-sibling::*[1][self::CHILDELEMENTNAME2)]>
The <sch:name /> element does not have CHILDELEMENTNAME2 preceding CHILDELEMENTNAME1
</sch:assert>
<sch:report test='ELEMENTNAME1 or ELEMENTNAME2' and not(ELEMENTNAME1 and ELEMENTNAME2)'>
The <sch:name /> element contains either ELEMENTNAME1 and ELEMENTNAME2 elements but not both
</sch:report>
<sch:report test='ELEMENTNAME1[not preceding-sibling::*[1]) or preceding-sibling::*[1][self::ELEMENTNAME1]]'>
The <sch:name /> element contains only ELEMENTNAME1 elements
</sch:report>
<sch:report test='count(ELEMENTNAME1[preceding-sibling::*[1][self::ELEMENTNAME1]]) + 1 = count(ELEMENTNAME1)'>
The <sch:name /> element contains only ELEMENTNAME1 elements
</sch:report>
<sch:report test='ELEMENTNAME2/preceding-sibling::ELEMENTNAME1 and ELEMENTNAME2/following-sibling::ELEMENTNAME1'>
The <sch:name /> element contains ELEMENTNAME2 elements in the middle of ELEMENTNAME1
</sch:report>
</sch:rule>
</sch:pattern>
<sch:pattern name='Validating Attributes'>
<sch:rule context='XPATH|ELEMENT'>
<sch:report test='@ATTRIBUTENAME'>
The <sch:name /> element has attribute ATTRIBUTENAME
</sch:report>
<sch:report test="@*[not(name()='ATTRIBUTENAME1' or name()='ATTRIBUTENAME2')]">
The <sch:name /> element does not contain attributes ATTRIBUTENAME1 or ATTRIBUTENAME2
</sch:report>
<sch:report test="@*[not(local-name()='PREFIX' and namespace-uri()='http//www.example.com')]">
The <sch:name /> element does not contain attributes in example:PREFIX namespace
</sch:report>
<sch:assert test='@*[not(namespace-uri())]'>
The <sch:name /> element has attributes in no namespace
</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern name='Validating strings'>
<sch:rule context='XPATH|ELEMENT'>
<sch:assert test="normalize-space()='VALUE'">
The <sch:name /> element does not have value of VALUE
</sch:assert>
<sch:assert test="translate(normalize-space(), 'VALUE', 'value') ='value'">
The <sch:name /> element does not have value of VALUE irrespective of case sensitivity
</sch:assert>
<sch:assert test='number()=NUMBER'>
The <sch:name /> element does not have a numberic value of NUMBER
</sch:assert>
<sch:assert test="number()=number()">
The <sch:name /> element does not have a numberic value
</sch:assert>
<sch:assert test='string-length()>= MINNUMBER and MAXNUMBER >= string-length()'>
The <sch:name /> element does not have a numberic value between MINNUMBER and MAXNUMBER
</sch:assert>
<sch:assert test="string()">
The <sch:name /> element is empty
</sch:assert>
<sch:assert
test="substring(.,7,4)=floor(substring(.,7,4)) and <-- YYYY is numberic -->
substring(.,4,2)=floor(substring(.,4,2)) and
substring(.,4,2)>=1 and 12 >= substring(.,4,2) <-- MM is numberic between 1 to 12 -->
substring(.,1,2)=floor(substring(.,1,2)) and
substring(.,1,2)>=1 and 31 >= substring(.,1,2) <-- DD is numberic between 1 to 31 -->
substring(.,3,1)='/' and substring(.,6,1)='/'">
The <sch:name /> element is not a valid date DD/MM/YYYY
</sch:assert>
<sch:assert test="number()=number()">
The <sch:name /> element is empty
</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern name='Co-occurrence constraints'>
<sch:assert context='XPATH|ELEMENT'>
test="ELEMENTNAME1='10000' and ELEMENTNAME2='OSGB" and string-length([ELEMENTNAME3])='4'">
The <sch:name /> element does not contain a validate 10km gridreference
</sch:assert>
</sch:pattern>
<sch:pattern name='Keys and References'>
<sch:rule context='XPATH|ELEMENT'>
<sch:key name='KEYNAME' path="concat(ELEMENTNAME1, '-', ELEMENTNAME2)" />
<sch:assert test="count(key('KEYNAME', concat(ELEMENTNAME1, '-', ELEMENTNAME2)))=1'>
The <sch:name /> element contains duplicate KEYNAME
</sch:assert>
<sch:key name='KEYNAME' path='@id' />
<sch:report test="string(ELEMENTNAME) and not (key('KEYNAME', ELEMENTNAME))">
The <sch:name /> element is not the same as the KEYNAME id value
</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
page_revision: 28, last_edited: 1256670130|%e %b %Y, %H:%M %Z (%O ago)






