summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Pokorný <jpokorny@redhat.com>2013-01-21 18:32:54 +0100
committerJan Pokorný <jpokorny@redhat.com>2013-01-21 18:32:54 +0100
commit73e9f64af524be2fc3a34ee1c473b64d12efbef2 (patch)
tree736a4c64f3d0e913498dae501bbdf3fb79aa12cc
downloadrnc2rng-73e9f64af524be2fc3a34ee1c473b64d12efbef2.tar.gz
rnc2rng-73e9f64af524be2fc3a34ee1c473b64d12efbef2.tar.xz
rnc2rng-73e9f64af524be2fc3a34ee1c473b64d12efbef2.zip
Initial commit, based on rnc.zip from gnosis.cx/download/relax
Complete URL: http://www.gnosis.cx/download/relax/rnc.zip Signed-off-by: David Mertz/www.gnosis.cx
-rw-r--r--README17
-rw-r--r--cardinality.rnc18
-rw-r--r--cardinality.rng31
-rw-r--r--clark.html33
-rw-r--r--conv08.rnc2
-rw-r--r--conv08.rng9
-rw-r--r--conv09.rng9
-rw-r--r--curious.dtd3
-rw-r--r--curious.xml3
-rw-r--r--lex.py681
-rw-r--r--patron-2.rng2
-rw-r--r--patron-i1.xml8
-rw-r--r--patron-i2.xml7
-rw-r--r--patron-i3.xml2
-rw-r--r--patron-v1.xml7
-rw-r--r--patron-v2.xml6
-rw-r--r--patron.rnc8
-rw-r--r--patron.rng19
-rw-r--r--patron.xsd24
-rw-r--r--regextest.rnc8
-rw-r--r--regextest.xml224
-rw-r--r--res08.rnc1
-rw-r--r--res08.rng9
-rw-r--r--res09.rng14
-rw-r--r--rnc2rng13
-rw-r--r--rnc_tokenize.py118
-rw-r--r--rnctree.py313
-rw-r--r--spectest.xml6845
-rw-r--r--split.xsl96
-rw-r--r--testSuite.rng157
-rwxr-xr-xxmlcat34
-rw-r--r--xsdtest.rnc22
-rw-r--r--xsdtest.rng108
-rw-r--r--xsdtest.xml805
-rw-r--r--xsdtest.xsl235
35 files changed, 9891 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..858ea6e
--- /dev/null
+++ b/README
@@ -0,0 +1,17 @@
+Example files and programming tools for working with RELAX NG
+
+Some of these files are part of James Clark's test suite (see
+clark.html for some details).
+
+All of the examples and scripts (unless indicated otherwise within
+the file) are released to the Public Domain.
+
++++
+
+To utilize the utility 'rnc2rng' download the following files,
+and place them in a working directory (or in your $PYTHONPATH):
+
+ rnc2rng
+ rnctree.py
+ rnc_tokenize.py
+ lex.py
diff --git a/cardinality.rnc b/cardinality.rnc
new file mode 100644
index 0000000..6cf4f90
--- /dev/null
+++ b/cardinality.rnc
@@ -0,0 +1,18 @@
+start = element bar { fivefoo, upto25foo }
+fivefoo =
+ element foo { empty },
+ element foo { empty },
+ element foo { empty },
+ element foo { empty },
+ element foo { empty }
+maybefoo = element foo { empty }?
+upto25foo =
+ fivefoo?,
+ fivefoo?,
+ fivefoo?,
+ fivefoo?,
+ maybefoo,
+ maybefoo,
+ maybefoo,
+ maybefoo,
+ maybefoo
diff --git a/cardinality.rng b/cardinality.rng
new file mode 100644
index 0000000..765d3e1
--- /dev/null
+++ b/cardinality.rng
@@ -0,0 +1,31 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="bar">
+ <ref name="fivefoo"/>
+ <ref name="upto25foo"/>
+ </element>
+ </start>
+ <define name="fivefoo">
+ <element name="foo"><empty/></element>
+ <element name="foo"><empty/></element>
+ <element name="foo"><empty/></element>
+ <element name="foo"><empty/></element>
+ <element name="foo"><empty/></element>
+ </define>
+ <define name="maybefoo">
+ <optional>
+ <element name="foo"><empty/></element>
+ </optional>
+ </define>
+ <define name="upto25foo">
+ <optional><ref name="fivefoo"/></optional>
+ <optional><ref name="fivefoo"/></optional>
+ <optional><ref name="fivefoo"/></optional>
+ <optional><ref name="fivefoo"/></optional>
+ <ref name="maybefoo"/>
+ <ref name="maybefoo"/>
+ <ref name="maybefoo"/>
+ <ref name="maybefoo"/>
+ <ref name="maybefoo"/>
+ </define>
+</grammar>
diff --git a/clark.html b/clark.html
new file mode 100644
index 0000000..1274ba0
--- /dev/null
+++ b/clark.html
@@ -0,0 +1,33 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>RELAX NG Test Suite</title>
+</head>
+<body>
+
+<p>This is a test suite for the final version of the <a
+href="http://www.oasis-open.org/committees/relax-ng/spec-20011203.html">RELAX
+NG 1.0 Specification</a>.</p>
+
+<p>The test suite consists of a single XML file <a
+href="spectest.xml">spectest.xml</a>, which includes over 300 test
+cases. Each test case consists of a correct or incorrect RELAX NG
+schema and zero or more valid or invalid instances. A RELAX NG <a
+href="testSuite.rng">schema</a> is available that specifies the format
+of the test suite.</p>
+
+<p>In order to run the test suite it may be convenient to split it up
+into separate files. An XSLT stylesheet <a
+href="split.xsl">split.xsl</a> is included to do this. This stylesheet
+uses <a href="http://saxon.sourceforge.net/">SAXON</a> extensions. <a
+href="http://www.thaiopensource.com/relaxng/jing.html">Jing</a>
+includes a class to run the test suite after it has been split up.
+The class is <code>com.thaiopensource.relaxng.util.TestDriver</code>.
+This class must be invoked with two arguments. The first argument is
+a log file for expected errors. The second argument is the directory
+containing the split-up test suite.</p>
+
+<address>
+<a href="mailto:jjc@jclark.com">James Clark</a>
+</address>
+</body>
+</html>
diff --git a/conv08.rnc b/conv08.rnc
new file mode 100644
index 0000000..42d4313
--- /dev/null
+++ b/conv08.rnc
@@ -0,0 +1,2 @@
+include "res08.rnc"
+foo.body = text
diff --git a/conv08.rng b/conv08.rng
new file mode 100644
index 0000000..53b69d0
--- /dev/null
+++ b/conv08.rng
@@ -0,0 +1,9 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<include href="res08.rng"/>
+
+<define name="foo.body">
+ <text/>
+</define>
+
+</grammar>
diff --git a/conv09.rng b/conv09.rng
new file mode 100644
index 0000000..a4298b3
--- /dev/null
+++ b/conv09.rng
@@ -0,0 +1,9 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<include href="res09.rng"/>
+
+<define name="y">
+ <ref name="z"/>
+</define>
+
+</grammar>
diff --git a/curious.dtd b/curious.dtd
new file mode 100644
index 0000000..03b6a63
--- /dev/null
+++ b/curious.dtd
@@ -0,0 +1,3 @@
+<!ELEMENT foo EMPTY>
+<!ATTLIST foo bar CDATA "curious"
+ baz CDATA #FIXED "curiouser">
diff --git a/curious.xml b/curious.xml
new file mode 100644
index 0000000..6d95294
--- /dev/null
+++ b/curious.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo SYSTEM "curious.dtd">
+<foo/>
diff --git a/lex.py b/lex.py
new file mode 100644
index 0000000..833213c
--- /dev/null
+++ b/lex.py
@@ -0,0 +1,681 @@
+#-----------------------------------------------------------------------------
+# ply: lex.py
+#
+# Author: David M. Beazley (beazley@cs.uchicago.edu)
+# Department of Computer Science
+# University of Chicago
+# Chicago, IL 60637
+#
+# Copyright (C) 2001, David M. Beazley
+#
+# $Header: /cvsroot/ply/ply/lex.py,v 1.7 2002/12/12 21:16:33 beazley Exp $
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See the file COPYING for a complete copy of the LGPL.
+#
+#
+# This module automatically constructs a lexical analysis module from regular
+# expression rules defined in a user-defined module. The idea is essentially the same
+# as that used in John Aycock's Spark framework, but the implementation works
+# at the module level rather than requiring the use of classes.
+#
+# This module tries to provide an interface that is closely modeled after
+# the traditional lex interface in Unix. It also differs from Spark
+# in that:
+#
+# - It provides more extensive error checking and reporting if
+# the user supplies a set of regular expressions that can't
+# be compiled or if there is any other kind of a problem in
+# the specification.
+#
+# - The interface is geared towards LALR(1) and LR(1) parser
+# generators. That is tokens are generated one at a time
+# rather than being generated in advanced all in one step.
+#
+# There are a few limitations of this module
+#
+# - The module interface makes it somewhat awkward to support more
+# than one lexer at a time. Although somewhat inelegant from a
+# design perspective, this is rarely a practical concern for
+# most compiler projects.
+#
+# - The lexer requires that the entire input text be read into
+# a string before scanning. I suppose that most machines have
+# enough memory to make this a minor issues, but it makes
+# the lexer somewhat difficult to use in interactive sessions
+# or with streaming data.
+#
+#-----------------------------------------------------------------------------
+
+r"""
+lex.py
+
+This module builds lex-like scanners based on regular expression rules.
+To use the module, simply write a collection of regular expression rules
+and actions like this:
+
+# lexer.py
+import lex
+
+# Define a list of valid tokens
+tokens = (
+ 'IDENTIFIER', 'NUMBER', 'PLUS', 'MINUS'
+ )
+
+# Define tokens as functions
+def t_IDENTIFIER(t):
+ r' ([a-zA-Z_](\w|_)* '
+ return t
+
+def t_NUMBER(t):
+ r' \d+ '
+ return t
+
+# Some simple tokens with no actions
+t_PLUS = r'\+'
+t_MINUS = r'-'
+
+# Initialize the lexer
+lex.lex()
+
+The tokens list is required and contains a complete list of all valid
+token types that the lexer is allowed to produce. Token types are
+restricted to be valid identifiers. This means that 'MINUS' is a valid
+token type whereas '-' is not.
+
+Rules are defined by writing a function with a name of the form
+t_rulename. Each rule must accept a single argument which is
+a token object generated by the lexer. This token has the following
+attributes:
+
+ t.type = type string of the token. This is initially set to the
+ name of the rule without the leading t_
+ t.value = The value of the lexeme.
+ t.lineno = The value of the line number where the token was encountered
+
+For example, the t_NUMBER() rule above might be called with the following:
+
+ t.type = 'NUMBER'
+ t.value = '42'
+ t.lineno = 3
+
+Each rule returns the token object it would like to supply to the
+parser. In most cases, the token t is returned with few, if any
+modifications. To discard a token for things like whitespace or
+comments, simply return nothing. For instance:
+
+def t_whitespace(t):
+ r' \s+ '
+ pass
+
+For faster lexing, you can also define this in terms of the ignore set like this:
+
+t_ignore = ' \t'
+
+The characters in this string are ignored by the lexer. Use of this feature can speed
+up parsing significantly since scanning will immediately proceed to the next token.
+
+lex requires that the token returned by each rule has an attribute
+t.type. Other than this, rules are free to return any kind of token
+object that they wish and may construct a new type of token object
+from the attributes of t (provided the new object has the required
+type attribute).
+
+If illegal characters are encountered, the scanner executes the
+function t_error(t) where t is a token representing the rest of the
+string that hasn't been matched. If this function isn't defined, a
+LexError exception is raised. The .text attribute of this exception
+object contains the part of the string that wasn't matched.
+
+The t.skip(n) method can be used to skip ahead n characters in the
+input stream. This is usually only used in the error handling rule.
+For instance, the following rule would print an error message and
+continue:
+
+def t_error(t):
+ print "Illegal character in input %s" % t.value[0]
+ t.skip(1)
+
+Of course, a nice scanner might wish to skip more than one character
+if the input looks very corrupted.
+
+The lex module defines a t.lineno attribute on each token that can be used
+to track the current line number in the input. The value of this
+variable is not modified by lex so it is up to your lexer module
+to correctly update its value depending on the lexical properties
+of the input language. To do this, you might write rules such as
+the following:
+
+def t_newline(t):
+ r' \n+ '
+ t.lineno += t.value.count("\n")
+
+To initialize your lexer so that it can be used, simply call the lex.lex()
+function in your rule file. If there are any errors in your
+specification, warning messages or an exception will be generated to
+alert you to the problem.
+
+(dave: this needs to be rewritten)
+To use the newly constructed lexer from another module, simply do
+this:
+
+ import lex
+ import lexer
+ plex.input("position = initial + rate*60")
+
+ while 1:
+ token = plex.token() # Get a token
+ if not token: break # No more tokens
+ ... do whatever ...
+
+Assuming that the module 'lexer' has initialized plex as shown
+above, parsing modules can safely import 'plex' without having
+to import the rule file or any additional imformation about the
+scanner you have defined.
+"""
+
+# -----------------------------------------------------------------------------
+
+
+__version__ = "1.3"
+
+import re, types, sys, copy
+
+# Exception thrown when invalid token encountered and no default
+class LexError(Exception):
+ def __init__(self,message,s):
+ self.args = (message,)
+ self.text = s
+
+# Token class
+class LexToken:
+ def __str__(self):
+ return "LexToken(%s,%r,%d)" % (self.type,self.value,self.lineno)
+ def __repr__(self):
+ return str(self)
+ def skip(self,n):
+ try:
+ self._skipn += n
+ except AttributeError:
+ self._skipn = n
+
+# -----------------------------------------------------------------------------
+# Lexer class
+#
+# input() - Store a new string in the lexer
+# token() - Get the next token
+# -----------------------------------------------------------------------------
+
+class Lexer:
+ def __init__(self):
+ self.lexre = None # Master regular expression
+ self.lexdata = None # Actual input data (as a string)
+ self.lexpos = 0 # Current position in input text
+ self.lexlen = 0 # Length of the input text
+ self.lexindexfunc = [ ] # Reverse mapping of groups to functions and types
+ self.lexerrorf = None # Error rule (if any)
+ self.lextokens = None # List of valid tokens
+ self.lexignore = None # Ignored characters
+ self.lineno = 1 # Current line number
+ self.debug = 0 # Debugging mode
+ self.optimize = 0 # Optimized mode
+ self.token = self.errtoken
+
+ def __copy__(self):
+ c = Lexer()
+ c.lexre = self.lexre
+ c.lexdata = self.lexdata
+ c.lexpos = self.lexpos
+ c.lexlen = self.lexlen
+ c.lenindexfunc = self.lexindexfunc
+ c.lexerrorf = self.lexerrorf
+ c.lextokens = self.lextokens
+ c.lexignore = self.lexignore
+ c.lineno = self.lineno
+ c.optimize = self.optimize
+ c.token = c.realtoken
+
+ # ------------------------------------------------------------
+ # input() - Push a new string into the lexer
+ # ------------------------------------------------------------
+ def input(self,s):
+ if not isinstance(s,types.StringType):
+ raise ValueError, "Expected a string"
+ self.lexdata = s
+ self.lexpos = 0
+ self.lexlen = len(s)
+ self.token = self.realtoken
+
+ # Change the token routine to point to realtoken()
+ global token
+ if token == self.errtoken:
+ token = self.token
+
+ # ------------------------------------------------------------
+ # errtoken() - Return error if token is called with no data
+ # ------------------------------------------------------------
+ def errtoken(self):
+ raise RuntimeError, "No input string given with input()"
+
+ # ------------------------------------------------------------
+ # token() - Return the next token from the Lexer
+ #
+ # Note: This function has been carefully implemented to be as fast
+ # as possible. Don't make changes unless you really know what
+ # you are doing
+ # ------------------------------------------------------------
+ def realtoken(self):
+ # Make local copies of frequently referenced attributes
+ lexpos = self.lexpos
+ lexlen = self.lexlen
+ lexignore = self.lexignore
+ lexdata = self.lexdata
+
+ while lexpos < lexlen:
+ # This code provides some short-circuit code for whitespace, tabs, and other ignored characters
+ if lexdata[lexpos] in lexignore:
+ lexpos += 1
+ continue
+
+ # Look for a regular expression match
+ m = self.lexre.match(lexdata,lexpos)
+ if m:
+ i = m.lastindex
+ lexpos = m.end()
+ tok = LexToken()
+ tok.value = m.group()
+ tok.lineno = self.lineno
+ tok.lexer = self
+ func,tok.type = self.lexindexfunc[i]
+ if not func:
+ self.lexpos = lexpos
+ return tok
+
+ # If token is processed by a function, call it
+ self.lexpos = lexpos
+ newtok = func(tok)
+ self.lineno = tok.lineno # Update line number
+
+ # Every function must return a token, if nothing, we just move to next token
+ if not newtok: continue
+
+ # Verify type of the token. If not in the token map, raise an error
+ if not self.optimize:
+ if not self.lextokens.has_key(newtok.type):
+ raise LexError, ("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
+ func.func_code.co_filename, func.func_code.co_firstlineno,
+ func.__name__, newtok.type),lexdata[lexpos:])
+
+ return newtok
+
+ # No match. Call t_error() if defined.
+ if self.lexerrorf:
+ tok = LexToken()
+ tok.value = self.lexdata[lexpos:]
+ tok.lineno = self.lineno
+ tok.type = "error"
+ tok.lexer = self
+ oldpos = lexpos
+ newtok = self.lexerrorf(tok)
+ lexpos += getattr(tok,"_skipn",0)
+ if oldpos == lexpos:
+ # Error method didn't change text position at all. This is an error.
+ self.lexpos = lexpos
+ raise LexError, ("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
+ if not newtok: continue
+ self.lexpos = lexpos
+ return newtok
+
+ self.lexpos = lexpos
+ raise LexError, ("No match found", lexdata[lexpos:])
+
+ # No more input data
+ self.lexpos = lexpos + 1
+ return None
+
+
+# -----------------------------------------------------------------------------
+# validate_file()
+#
+# This checks to see if there are duplicated t_rulename() functions or strings
+# in the parser input file. This is done using a simple regular expression
+# match on each line in the filename.
+# -----------------------------------------------------------------------------
+
+def validate_file(filename):
+ import os.path
+ base,ext = os.path.splitext(filename)
+ if ext != '.py': return 1 # No idea what the file is. Return OK
+
+ try:
+ f = open(filename)
+ lines = f.readlines()
+ f.close()
+ except IOError:
+ return 1 # Oh well
+
+ fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
+ sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
+ counthash = { }
+ linen = 1
+ noerror = 1
+ for l in lines:
+ m = fre.match(l)
+ if not m:
+ m = sre.match(l)
+ if m:
+ name = m.group(1)
+ prev = counthash.get(name)
+ if not prev:
+ counthash[name] = linen
+ else:
+ print "%s:%d: Rule %s redefined. Previously defined on line %d" % (filename,linen,name,prev)
+ noerror = 0
+ linen += 1
+ return noerror
+
+# -----------------------------------------------------------------------------
+# _read_lextab(module)
+#
+# Reads lexer table from a lextab file instead of using introspection.
+# -----------------------------------------------------------------------------
+
+def _read_lextab(lexer, fdict, module):
+ exec "import %s as lextab" % module
+ lexer.lexre = re.compile(lextab._lexre, re.VERBOSE)
+ lexer.lexindexfunc = lextab._lextab
+ for i in range(len(lextab._lextab)):
+ t = lexer.lexindexfunc[i]
+ if t:
+ if t[0]:
+ lexer.lexindexfunc[i] = (fdict[t[0]],t[1])
+ lexer.lextokens = lextab._lextokens
+ lexer.lexignore = lextab._lexignore
+ if lextab._lexerrorf:
+ lexer.lexerrorf = fdict[lextab._lexerrorf]
+
+# -----------------------------------------------------------------------------
+# lex(module)
+#
+# Build all of the regular expression rules from definitions in the supplied module
+# -----------------------------------------------------------------------------
+def lex(module=None,debug=0,optimize=0,lextab="lextab"):
+ ldict = None
+ regex = ""
+ error = 0
+ files = { }
+ lexer = Lexer()
+ lexer.debug = debug
+ lexer.optimize = optimize
+ global token,input
+
+ if module:
+ if not isinstance(module, types.ModuleType):
+ raise ValueError,"Expected a module"
+
+ ldict = module.__dict__
+
+ else:
+ # No module given. We might be able to get information from the caller.
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ e,b,t = sys.exc_info()
+ f = t.tb_frame
+ f = f.f_back # Walk out to our calling function
+ ldict = f.f_globals # Grab its globals dictionary
+
+ if optimize and lextab:
+ try:
+ _read_lextab(lexer,ldict, lextab)
+ if not lexer.lexignore: lexer.lexignore = ""
+ token = lexer.token
+ input = lexer.input
+ return lexer
+
+ except ImportError:
+ pass
+
+ # Get the tokens map
+ tokens = ldict.get("tokens",None)
+ if not tokens:
+ raise SyntaxError,"lex: module does not define 'tokens'"
+ if not (isinstance(tokens,types.ListType) or isinstance(tokens,types.TupleType)):
+ raise SyntaxError,"lex: tokens must be a list or tuple."
+
+ # Build a dictionary of valid token names
+ lexer.lextokens = { }
+ if not optimize:
+
+ # Utility function for verifying tokens
+ def is_identifier(s):
+ for c in s:
+ if not (c.isalnum() or c == '_'): return 0
+ return 1
+
+ for n in tokens:
+ if not is_identifier(n):
+ print "lex: Bad token name '%s'" % n
+ error = 1
+ if lexer.lextokens.has_key(n):
+ print "lex: Warning. Token '%s' multiply defined." % n
+ lexer.lextokens[n] = None
+ else:
+ for n in tokens: lexer.lextokens[n] = None
+
+
+ if debug:
+ print "lex: tokens = '%s'" % lexer.lextokens.keys()
+
+ # Get a list of symbols with the t_ prefix
+ tsymbols = [f for f in ldict.keys() if f[:2] == 't_']
+
+ # Now build up a list of functions and a list of strings
+ fsymbols = [ ]
+ ssymbols = [ ]
+ for f in tsymbols:
+ if isinstance(ldict[f],types.FunctionType):
+ fsymbols.append(ldict[f])
+ elif isinstance(ldict[f],types.StringType):
+ ssymbols.append((f,ldict[f]))
+ else:
+ print "lex: %s not defined as a function or string" % f
+ error = 1
+
+ # Sort the functions by line number
+ fsymbols.sort(lambda x,y: cmp(x.func_code.co_firstlineno,y.func_code.co_firstlineno))
+
+ # Sort the strings by regular expression length
+ ssymbols.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1])))
+
+ # Check for non-empty symbols
+ if len(fsymbols) == 0 and len(ssymbols) == 0:
+ raise SyntaxError,"lex: no rules of the form t_rulename are defined."
+
+ # Add all of the rules defined with actions first
+ for f in fsymbols:
+
+ line = f.func_code.co_firstlineno
+ file = f.func_code.co_filename
+ files[file] = None
+
+ if not optimize:
+ if f.func_code.co_argcount > 1:
+ print "%s:%d: Rule '%s' has too many arguments." % (file,line,f.__name__)
+ error = 1
+ continue
+
+ if f.func_code.co_argcount < 1:
+ print "%s:%d: Rule '%s' requires an argument." % (file,line,f.__name__)
+ error = 1
+ continue
+
+ if f.__name__ == 't_ignore':
+ print "%s:%d: Rule '%s' must be defined as a string." % (file,line,f.__name__)
+ error = 1
+ continue
+
+ if f.__name__ == 't_error':
+ lexer.lexerrorf = f
+ continue
+
+ if f.__doc__:
+ if not optimize:
+ try:
+ c = re.compile(f.__doc__, re.VERBOSE)
+ except re.error,e:
+ print "%s:%d: Invalid regular expression for rule '%s'. %s" % (file,line,f.__name__,e)
+ error = 1
+ continue
+
+ if debug:
+ print "lex: Adding rule %s -> '%s'" % (f.__name__,f.__doc__)
+
+ # Okay. The regular expression seemed okay. Let's append it to the master regular
+ # expression we're building
+
+ if (regex): regex += "|"
+ regex += "(?P<%s>%s)" % (f.__name__,f.__doc__)
+ else:
+ print "%s:%d: No regular expression defined for rule '%s'" % (file,line,f.__name__)
+
+ # Now add all of the simple rules
+ for name,r in ssymbols:
+
+ if name == 't_ignore':
+ lexer.lexignore = r
+ continue
+
+ if not optimize:
+ if name == 't_error':
+ raise SyntaxError,"lex: Rule 't_error' must be defined as a function"
+ error = 1
+ continue
+
+ if not lexer.lextokens.has_key(name[2:]):
+ print "lex: Rule '%s' defined for an unspecified token %s." % (name,name[2:])
+ error = 1
+ continue
+ try:
+ c = re.compile(r,re.VERBOSE)
+ except re.error,e:
+ print "lex: Invalid regular expression for rule '%s'. %s" % (name,e)
+ error = 1
+ continue
+ if debug:
+ print "lex: Adding rule %s -> '%s'" % (name,r)
+
+ if regex: regex += "|"
+ regex += "(?P<%s>%s)" % (name,r)
+
+ if not optimize:
+ for f in files.keys():
+ if not validate_file(f):
+ error = 1
+ try:
+ if debug:
+ print "lex: regex = '%s'" % regex
+ lexer.lexre = re.compile(regex, re.VERBOSE)
+
+ # Build the index to function map for the matching engine
+ lexer.lexindexfunc = [ None ] * (max(lexer.lexre.groupindex.values())+1)
+ for f,i in lexer.lexre.groupindex.items():
+ handle = ldict[f]
+ if isinstance(handle,types.FunctionType):
+ lexer.lexindexfunc[i] = (handle,handle.__name__[2:])
+ else:
+ # If rule was specified as a string, we build an anonymous
+ # callback function to carry out the action
+ lexer.lexindexfunc[i] = (None,f[2:])
+
+ # If a lextab was specified, we create a file containing the precomputed
+ # regular expression and index table
+
+ if lextab and optimize:
+ lt = open(lextab+".py","w")
+ lt.write("# %s.py. This file automatically created by PLY. Don't edit.\n" % lextab)
+ lt.write("_lexre = %s\n" % repr(regex))
+ lt.write("_lextab = [\n");
+ for i in range(0,len(lexer.lexindexfunc)):
+ t = lexer.lexindexfunc[i]
+ if t:
+ if t[0]:
+ lt.write(" ('%s',%s),\n"% (t[0].__name__, repr(t[1])))
+ else:
+ lt.write(" (None,%s),\n" % repr(t[1]))
+ else:
+ lt.write(" None,\n")
+
+ lt.write("]\n");
+ lt.write("_lextokens = %s\n" % repr(lexer.lextokens))
+ lt.write("_lexignore = %s\n" % repr(lexer.lexignore))
+ if (lexer.lexerrorf):
+ lt.write("_lexerrorf = %s\n" % repr(lexer.lexerrorf.__name__))
+ else:
+ lt.write("_lexerrorf = None\n")
+ lt.close()
+
+ except re.error,e:
+ print "lex: Fatal error. Unable to compile regular expression rules. %s" % e
+ error = 1
+ if error:
+ raise SyntaxError,"lex: Unable to build lexer."
+ if not lexer.lexerrorf:
+ print "lex: Warning. no t_error rule is defined."
+
+ if not lexer.lexignore: lexer.lexignore = ""
+
+ # Create global versions of the token() and input() functions
+ token = lexer.token
+ input = lexer.input
+
+ return lexer
+
+# -----------------------------------------------------------------------------
+# run()
+#
+# This runs the lexer as a main program
+# -----------------------------------------------------------------------------
+
+def runmain(lexer=None,data=None):
+ if not data:
+ try:
+ filename = sys.argv[1]
+ f = open(filename)
+ data = f.read()
+ f.close()
+ except IndexError:
+ print "Reading from standard input (type EOF to end):"
+ data = sys.stdin.read()
+
+ if lexer:
+ _input = lexer.input
+ else:
+ _input = input
+ _input(data)
+ if lexer:
+ _token = lexer.token
+ else:
+ _token = token
+
+ while 1:
+ tok = _token()
+ if not tok: break
+ print "(%s,'%s',%d)" % (tok.type, tok.value, tok.lineno)
+
+
+
+
diff --git a/patron-2.rng b/patron-2.rng
new file mode 100644
index 0000000..324138e
--- /dev/null
+++ b/patron-2.rng
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"><start><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></start><define name="start-element"><element><name ns="http://relaxng.org/ns/structure/1.0">start</name><group><group><choice><empty/><attribute><name ns="">combine</name><choice><value datatypeLibrary="" ns="http://relaxng.org/ns/structure/1.0" type="token">choice</value><value datatypeLibrary="" ns="http://relaxng.org/ns/structure/1.0" type="token">interleave</value></choice></attribute></choice><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></interleave></group></element></define><define name="any"><element><anyName/><choice><empty/><oneOrMore><choice><choice><attribute><anyName/><text/></attribute><text/></choice><ref name="any"/></choice></oneOrMore></choice></element></define><define name="define-element"><element><name ns="http://relaxng.org/ns/structure/1.0">define</name><group><group><group><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute><choice><empty/><attribute><name ns="">combine</name><choice><value datatypeLibrary="" ns="http://relaxng.org/ns/structure/1.0" type="token">choice</value><value datatypeLibrary="" ns="http://relaxng.org/ns/structure/1.0" type="token">interleave</value></choice></attribute></choice></group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="except_"><element><name ns="http://relaxng.org/ns/structure/1.0">except</name><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><ref name="name_"/><ref name="anyName_"/></choice><ref name="nsName_"/></choice><ref name="choice_"/></choice></oneOrMore></interleave></element></define><define name="name_"><element><name ns="http://relaxng.org/ns/structure/1.0">name</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="QName"/></group></element></define><define name="anyName_"><element><name ns="http://relaxng.org/ns/structure/1.0">anyName</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><ref name="except_"/></choice></interleave></group></element></define><define name="nsName_"><element><name ns="http://relaxng.org/ns/structure/1.0">nsName</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><ref name="except_"/></choice></interleave></group></element></define><define name="choice_"><element><name ns="http://relaxng.org/ns/structure/1.0">choice</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><ref name="name_"/><ref name="anyName_"/></choice><ref name="nsName_"/></choice><ref name="choice_"/></choice></oneOrMore></interleave></group></element></define><define name="div_"><element><name ns="http://relaxng.org/ns/structure/1.0">div</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><oneOrMore><choice><choice><choice><ref name="start-element"/><ref name="define-element"/></choice><ref name="div_"/></choice><ref name="include_"/></choice></oneOrMore></choice></interleave></group></element></define><define name="include_"><element><name ns="http://relaxng.org/ns/structure/1.0">include</name><group><group><attribute><name ns="">href</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><oneOrMore><choice><choice><ref name="start-element"/><ref name="define-element"/></choice><ref name="div_s"/></choice></oneOrMore></choice></interleave></group></element></define><define name="_"><element><anyName><except><nsName ns="http://relaxng.org/ns/structure/1.0"/></except></anyName><choice><empty/><oneOrMore><choice><choice><attribute><anyName/><text/></attribute><text/></choice><ref name="any"/></choice></oneOrMore></choice></element></define><define name="element_"><element><name ns="http://relaxng.org/ns/structure/1.0">element</name><group><group><choice><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="QName"/></attribute><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><choice><choice><ref name="name_"/><ref name="anyName_"/></choice><ref name="nsName_"/></choice><ref name="choice_"/></choice></interleave></choice><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="attribute_"><element><name ns="http://relaxng.org/ns/structure/1.0">attribute</name><group><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><choice><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="QName"/></attribute><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><choice><choice><ref name="name_"/><ref name="anyName_"/></choice><ref name="nsName_"/></choice><ref name="choice_"/></choice></interleave></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></choice></interleave></group></element></define><define name="group_"><element><name ns="http://relaxng.org/ns/structure/1.0">group</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="interleave_"><element><name ns="http://relaxng.org/ns/structure/1.0">interleave</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="choice_s"><element><name ns="http://relaxng.org/ns/structure/1.0">choice</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="optional_"><element><name ns="http://relaxng.org/ns/structure/1.0">optional</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="zeroOrMore_"><element><name ns="http://relaxng.org/ns/structure/1.0">zeroOrMore</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="oneOrMore_"><element><name ns="http://relaxng.org/ns/structure/1.0">oneOrMore</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="list_"><element><name ns="http://relaxng.org/ns/structure/1.0">list</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="mixed_"><element><name ns="http://relaxng.org/ns/structure/1.0">mixed</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define><define name="ref_"><element><name ns="http://relaxng.org/ns/structure/1.0">ref</name><group><group><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice></group></element></define><define name="parentRef_"><element><name ns="http://relaxng.org/ns/structure/1.0">parentRef</name><group><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group></element></define><define name="empty_"><element><name ns="http://relaxng.org/ns/structure/1.0">empty</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice></group></element></define><define name="text_"><element><name ns="http://relaxng.org/ns/structure/1.0">text</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice></group></element></define><define name="value_"><element><name ns="http://relaxng.org/ns/structure/1.0">value</name><group><group><choice><empty/><attribute><name ns="">type</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute></choice><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><text/></group></element></define><define name="data_"><element><name ns="http://relaxng.org/ns/structure/1.0">data</name><group><group><attribute><name ns="">type</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><group><choice><empty/><oneOrMore><ref name="param_"/></oneOrMore></choice><choice><empty/><ref name="except_x"/></choice></group></interleave></group></element></define><define name="notAllowed_"><element><name ns="http://relaxng.org/ns/structure/1.0">notAllowed</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice></group></element></define><define name="externalRef_"><element><name ns="http://relaxng.org/ns/structure/1.0">externalRef</name><group><group><attribute><name ns="">href</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice></group></element></define><define name="grammar_"><element><name ns="http://relaxng.org/ns/structure/1.0">grammar</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><oneOrMore><choice><choice><choice><ref name="start-element"/><ref name="define-element"/></choice><ref name="div_"/></choice><ref name="include_"/></choice></oneOrMore></choice></interleave></group></element></define><define name="div_s"><element><name ns="http://relaxng.org/ns/structure/1.0">div</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><choice><empty/><oneOrMore><choice><choice><ref name="start-element"/><ref name="define-element"/></choice><ref name="div_s"/></choice></oneOrMore></choice></interleave></group></element></define><define name="param_"><element><name ns="http://relaxng.org/ns/structure/1.0">param</name><group><group><attribute><name ns="">name</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="NCName"/></attribute><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group></group><text/></group></element></define><define name="except_x"><element><name ns="http://relaxng.org/ns/structure/1.0">except</name><group><group><group><choice><empty/><attribute><name ns="">ns</name><text/></attribute></choice><choice><empty/><attribute><name ns="">datatypeLibrary</name><data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="anyURI"/></attribute></choice></group><choice><empty/><oneOrMore><attribute><anyName><except><choice><nsName ns="http://relaxng.org/ns/structure/1.0"/><nsName ns=""/></choice></except></anyName><text/></attribute></oneOrMore></choice></group><interleave><choice><empty/><oneOrMore><ref name="_"/></oneOrMore></choice><oneOrMore><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><choice><ref name="element_"/><ref name="attribute_"/></choice><ref name="group_"/></choice><ref name="interleave_"/></choice><ref name="choice_s"/></choice><ref name="optional_"/></choice><ref name="zeroOrMore_"/></choice><ref name="oneOrMore_"/></choice><ref name="list_"/></choice><ref name="mixed_"/></choice><ref name="ref_"/></choice><ref name="parentRef_"/></choice><ref name="empty_"/></choice><ref name="text_"/></choice><ref name="value_"/></choice><ref name="data_"/></choice><ref name="notAllowed_"/></choice><ref name="externalRef_"/></choice><ref name="grammar_"/></choice></oneOrMore></interleave></group></element></define></grammar> \ No newline at end of file
diff --git a/patron-i1.xml b/patron-i1.xml
new file mode 100644
index 0000000..976be53
--- /dev/null
+++ b/patron-i1.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patron>
+ <book isbn="0-528-84460-X"/>
+ <name>John Doe</name>
+ <name>Second Name</name>
+ <id-num>12345678</id-num>
+ <book title="Why RELAX is Clever"/>
+</patron>
diff --git a/patron-i2.xml b/patron-i2.xml
new file mode 100644
index 0000000..f0b38c5
--- /dev/null
+++ b/patron-i2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patron>
+ <name>John Doe</name>
+ <id-num>12345678</id-num>
+ <book title="Why RELAX is Clever" isbn="0-528-84460-X"/>
+ <book/>
+</patron>
diff --git a/patron-i3.xml b/patron-i3.xml
new file mode 100644
index 0000000..fba69c8
--- /dev/null
+++ b/patron-i3.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patron/>
diff --git a/patron-v1.xml b/patron-v1.xml
new file mode 100644
index 0000000..1676598
--- /dev/null
+++ b/patron-v1.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patron>
+ <book isbn="0-528-84460-X"/>
+ <name>John Doe</name>
+ <id-num>12345678</id-num>
+ <book title="Why RELAX is Clever"/>
+</patron>
diff --git a/patron-v2.xml b/patron-v2.xml
new file mode 100644
index 0000000..06b37bb
--- /dev/null
+++ b/patron-v2.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patron>
+ <id-num>09876545</id-num>
+ <name>Jane Moe</name>
+</patron>
+
diff --git a/patron.rnc b/patron.rnc
new file mode 100644
index 0000000..37d7f03
--- /dev/null
+++ b/patron.rnc
@@ -0,0 +1,8 @@
+element patron {
+ element name { text }
+ & element id-num { text }
+ & element book {
+ attribute isbn { text }
+ | attribute title { text }
+ }*
+}
diff --git a/patron.rng b/patron.rng
new file mode 100644
index 0000000..582ad0f
--- /dev/null
+++ b/patron.rng
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<element name="patron" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="name">
+ <text/>
+ </element>
+ <element name="id-num">
+ <text/>
+ </element>
+ <zeroOrMore>
+ <element name="book">
+ <choice>
+ <attribute name="isbn"/>
+ <attribute name="title"/>
+ </choice>
+ </element>
+ </zeroOrMore>
+ </interleave>
+</element>
diff --git a/patron.xsd b/patron.xsd
new file mode 100644
index 0000000..420bb3d
--- /dev/null
+++ b/patron.xsd
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="1.0">
+ <xs:element name="patron">
+ <xs:complexType>
+ <xs:choice minOccurs="0" maxOccurs="unbounded">
+ <xs:element ref="name"/>
+ <xs:element ref="id-num"/>
+ <xs:element ref="book"/>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="name">
+ <xs:complexType mixed="true"/>
+ </xs:element>
+ <xs:element name="id-num">
+ <xs:complexType mixed="true"/>
+ </xs:element>
+ <xs:element name="book">
+ <xs:complexType>
+ <xs:attribute name="isbn"/>
+ <xs:attribute name="title"/>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
diff --git a/regextest.rnc b/regextest.rnc
new file mode 100644
index 0000000..47950b1
--- /dev/null
+++ b/regextest.rnc
@@ -0,0 +1,8 @@
+# A schema for regextest.rnc in RELAX NG compact syntax
+
+element testSuite {
+ element testCase {
+ (element correct { text }, element valid|invalid { text }*)
+ | element incorrect { text }
+ }*
+}
diff --git a/regextest.xml b/regextest.xml
new file mode 100644
index 0000000..496886f
--- /dev/null
+++ b/regextest.xml
@@ -0,0 +1,224 @@
+<testSuite>
+<testCase>
+<correct>xyzzy</correct>
+<valid>xyzzy</valid>
+<invalid>xyzz</invalid>
+<invalid>xyzzyy</invalid>
+<invalid>xxyzzy</invalid>
+<invalid>XYZZY</invalid>
+<invalid> xyzzy</invalid>
+</testCase>
+<testCase>
+<correct>\i</correct>
+<valid>j</valid>
+<valid>&#x212E;</valid>
+</testCase>
+<testCase>
+<incorrect>a??</incorrect>
+</testCase>
+<testCase>
+<correct>\P{IsGothic}</correct>
+<invalid>&#x10330;</invalid>
+<invalid>&#x1033F;</invalid>
+<invalid>&#x1034F;</invalid>
+<valid>X</valid>
+<valid>&#x1032F;</valid>
+<valid>&#x20330;</valid>
+<valid>&#x30330;</valid>
+<valid>&#x10350;</valid>
+</testCase>
+<testCase>
+<correct>\p{IsGothic}</correct>
+<valid>&#x10330;</valid>
+<valid>&#x1033F;</valid>
+<valid>&#x1034F;</valid>
+<invalid>X</invalid>
+<invalid>&#x1032F;</invalid>
+<invalid>&#x20330;</invalid>
+<invalid>&#x30330;</invalid>
+<invalid>&#x10350;</invalid>
+</testCase>
+<testCase>
+<correct>$</correct>
+<valid>$</valid>
+<invalid/>
+</testCase>
+<testCase>
+<correct>a|b</correct>
+</testCase>
+<testCase>
+<correct>[x-y]</correct>
+</testCase>
+<testCase>
+<correct>[\p{Nd}-[a-z]]</correct>
+</testCase>
+<testCase>
+<correct>[\p{Nd}-[\p{IsThai}]]</correct>
+</testCase>
+<testCase>
+<correct>\p{IsThai}</correct>
+</testCase>
+<testCase>
+<correct>\i\c*</correct>
+</testCase>
+<testCase>
+<correct>~!@#$%\^&amp;\*\(\)_\+`\-=\{\}\[\]\|\\:;"',\.&lt;>/\?</correct>
+<valid>~!@#$%^&amp;*()_+`-={}[]|\:;"',.&lt;>/?</valid>
+</testCase>
+<testCase>
+<correct>[f&amp;&amp;g]</correct>
+<valid>f</valid>
+<valid>&amp;</valid>
+<valid>g</valid>
+</testCase>
+<testCase>
+<correct>^</correct>
+<valid>^</valid>
+</testCase>
+<testCase>
+<incorrect>\</incorrect>
+</testCase>
+<testCase>
+<incorrect>?</incorrect>
+</testCase>
+<testCase>
+<incorrect>*</incorrect>
+</testCase>
+<testCase>
+<incorrect>+</incorrect>
+</testCase>
+<testCase>
+<incorrect>)</incorrect>
+</testCase>
+<testCase>
+<incorrect>(</incorrect>
+</testCase>
+<testCase>
+<incorrect>[</incorrect>
+</testCase>
+<testCase>
+<incorrect>]</incorrect>
+</testCase>
+<testCase>
+<correct>-</correct>
+<valid>-</valid>
+</testCase>
+<testCase>
+<correct>|</correct>
+<valid/>
+<invalid>|</invalid>
+</testCase>
+<testCase>
+<correct>.</correct>
+<valid>.</valid>
+<invalid/>
+<invalid>
+</invalid>
+<invalid>&#xA;</invalid>
+<invalid>&#xD;</invalid>
+<invalid>..</invalid>
+<valid>&#x10330;</valid>
+</testCase>
+<testCase>
+<incorrect>[^]</incorrect>
+</testCase>
+<testCase>
+<incorrect>[]</incorrect>
+</testCase>
+<testCase>
+<incorrect>[]]</incorrect>
+</testCase>
+<testCase>
+<incorrect>[[]</incorrect>
+</testCase>
+<testCase>
+<incorrect>[\]</incorrect>
+</testCase>
+<testCase>
+<correct>[^^]</correct>
+<valid>x</valid>
+<invalid>^</invalid>
+</testCase>
+<testCase>
+<correct>[?+*(){}|.]</correct>
+<valid>?</valid>
+<valid>+</valid>
+<valid>*</valid>
+<valid>(</valid>
+<valid>)</valid>
+<valid>{</valid>
+<valid>}</valid>
+<valid>|</valid>
+<valid>.</valid>
+<invalid>x</invalid>
+</testCase>
+<testCase>
+<correct/>
+<valid/>
+<invalid>x</invalid>
+</testCase>
+<testCase>
+<incorrect>x{2,1}</incorrect>
+</testCase>
+<testCase>
+<correct>x{1,1}</correct>
+<valid>x</valid>
+</testCase>
+<testCase>
+<incorrect>x{1, 2}</incorrect>
+</testCase>
+<testCase>
+<incorrect>x{ 2}</incorrect>
+</testCase>
+<testCase>
+<incorrect>x{2 }</incorrect>
+</testCase>
+<testCase>
+<incorrect>x{-0,1}</incorrect>
+</testCase>
+<testCase>
+<incorrect>x{+2}</incorrect>
+</testCase>
+<testCase>
+<correct>x{2147483648}</correct>
+<invalid>x</invalid>
+</testCase>
+<testCase>
+<incorrect>x{2147483649,2147483648}</incorrect>
+</testCase>
+<testCase>
+<correct>x{0,2147483648}</correct>
+<valid>x</valid>
+</testCase>
+<testCase>
+<correct>[a-z-[c-y]]</correct>
+<valid>a</valid>
+<valid>b</valid>
+<valid>z</valid>
+<invalid>c</invalid>
+<invalid>y</invalid>
+<invalid>d</invalid>
+</testCase>
+<testCase>
+<correct>[abc-[a-a]]</correct>
+<valid>b</valid>
+<valid>c</valid>
+<invalid>a</invalid>
+<invalid>d</invalid>
+</testCase>
+<testCase>
+<incorrect>[a-[a]-[a]]</incorrect>
+</testCase>
+<testCase>
+<incorrect>\pL</incorrect>
+</testCase>
+<testCase>
+<correct>\p{IsHighSurrogates}\p{IsLowSurrogates}</correct>
+<invalid>&#x10330;</invalid>
+</testCase>
+<testCase>
+<correct>a[&#x10330;-[&#x10330;]]*b</correct>
+<valid>ab</valid>
+<invalid>a&#x10330;b</invalid>
+</testCase>
+</testSuite>
diff --git a/res08.rnc b/res08.rnc
new file mode 100644
index 0000000..90847a2
--- /dev/null
+++ b/res08.rnc
@@ -0,0 +1 @@
+start = element foo { foo.body }
diff --git a/res08.rng b/res08.rng
new file mode 100644
index 0000000..951942f
--- /dev/null
+++ b/res08.rng
@@ -0,0 +1,9 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<start>
+<element name="foo">
+ <ref name="foo.body"/>
+</element>
+</start>
+
+</grammar>
diff --git a/res09.rng b/res09.rng
new file mode 100644
index 0000000..ce652f6
--- /dev/null
+++ b/res09.rng
@@ -0,0 +1,14 @@
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<start>
+<element name="foo">
+ <ref name="y"/>
+</element>
+</start>
+
+<define name="z">
+ <text/>
+</define>
+
+
+</grammar>
diff --git a/rnc2rng b/rnc2rng
new file mode 100644
index 0000000..7312b99
--- /dev/null
+++ b/rnc2rng
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import sys
+from rnctree import make_nodetree, token_list
+if len(sys.argv) > 1:
+ tokens = token_list(open(sys.argv[1]).read())
+else:
+ tokens = token_list(sys.stdin.read())
+root = make_nodetree(tokens)
+if len(sys.argv) > 2:
+ open(sys.argv[2],'w').write(root.toxml())
+else:
+ print root.toxml()
+
diff --git a/rnc_tokenize.py b/rnc_tokenize.py
new file mode 100644
index 0000000..20cfc34
--- /dev/null
+++ b/rnc_tokenize.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# Define the tokenizer for RELAX NG compact syntax
+# This file released to the Public Domain by David Mertz
+import lex
+tokens = tuple('''
+ ELEM ATTR EMPTY TEXT KEYWORD LITERAL ANNOTATION COMMENT
+ BEG_PAREN END_PAREN BEG_BODY END_BODY EQUAL NAME CHOICE SEQ
+ INTERLEAVE ANY SOME MAYBE WHITESPACE TODO DATATAG PATTERN
+ DEFAULT_NS NS DATATYPES NS_ANNOTATION START DEFINE
+ '''.split())
+
+reserved = {
+ 'element' : 'ELEM',
+ 'attribute' : 'ATTR',
+ 'empty' : 'EMPTY',
+ 'text' : 'TEXT',
+ 'div' : 'TODO',
+ 'external' : 'TODO',
+ 'grammar' : 'TODO',
+ 'include' : 'TODO',
+ 'inherit' : 'TODO',
+ 'list' : 'TODO',
+ 'mixed' : 'TODO',
+ 'notAllowed' : 'TODO',
+ 'parent' : 'TODO',
+ 'string' : 'TODO',
+ 'token' : 'TODO',
+}
+
+def t_START(t):
+ r"(?im)^start\s*=\s*.*$"
+ t.value = t.value.split('=')[1].strip()
+ return t
+
+def t_DEFINE(t):
+ r"(?im)^[\w-]+\s*="
+ t.value = t.value.split('=')[0].strip()
+ return t
+
+def t_ANNOTATION(t):
+ r"(?im)^\#\# .*$"
+ t.value = t.value[3:]
+ return t
+
+def t_COMMENT(t):
+ r"(?im)^\# .*$"
+ t.value = t.value[2:]
+ return t
+
+def t_DEFAULT_NS(t):
+ r"(?im)default\s+namespace\s*=\s*.*$"
+ t.value = t.value.split('=')[1].strip()
+ return t
+
+def t_DATATYPES(t):
+ r"(?im)datatypes\s+xsd\s*=\s*.*$"
+ t.value = t.value.split('=')[1].strip()
+ return t
+
+def t_DATATAG(t):
+ r"xsd:\w+"
+ t.value = t.value.split(':')[1]
+ return t
+
+def t_PATTERN(t):
+ r'{\s*pattern\s*=\s*".*"\s*}'
+ t.value = t.value[:-1].split('=')[1].strip()[1:-1]
+ return t
+
+def t_NS(t):
+ r"(?im)^namespace\s+.*$"
+ t.value = t.value.split(None,1)[1]
+ return t
+
+def t_ID(t):
+ r"[\w:_-]+"
+ t.type = reserved.get(t.value,'NAME') # Check for reserved words
+ return t
+
+def t_LITERAL(t):
+ r'".+?"'
+ t.value = t.value[1:-1]
+ return t
+
+t_BEG_PAREN = r"\("
+t_END_PAREN = r"\)"
+t_BEG_BODY = r"{"
+t_END_BODY = r"}"
+t_EQUAL = r"="
+t_CHOICE = r"[|]"
+t_SEQ = r","
+t_INTERLEAVE= r"&"
+t_ANY = r"[*]"
+t_SOME = r"[+]"
+t_MAYBE = r"[?]"
+t_WHITESPACE= r"\s+"
+t_ignore = " \t\n\r"
+
+def t_error(t):
+ t.skip(1)
+
+def token_list(rnc):
+ lex.lex()
+ lex.input(rnc)
+ ts = []
+ while 1:
+ t = lex.token()
+ if t is None:
+ break
+ ts.append(t)
+ return ts
+
+if __name__=='__main__':
+ import sys
+ del t_ignore
+ tokens = token_list(sys.stdin.read())
+ print '\n'.join(map(repr, tokens))
diff --git a/rnctree.py b/rnctree.py
new file mode 100644
index 0000000..0735444
--- /dev/null
+++ b/rnctree.py
@@ -0,0 +1,313 @@
+#!/usr/bin/env python
+# Convert an RELAX NG compact syntax schema to a Node tree
+# This file released to the Public Domain by David Mertz
+from __future__ import generators
+import sys
+from rnc_tokenize import token_list
+
+class ParseError(SyntaxError): pass
+
+for t in """
+ ANY SOME MAYBE ONE BODY ANNOTATION ELEM ATTR GROUP LITERAL
+ NAME COMMENT TEXT EMPTY INTERLEAVE CHOICE SEQ ROOT
+ DEFAULT_NS NS DATATYPES DATATAG PATTERN START DEFINE
+ """.split(): globals()[t] = t
+
+PAIRS = {'BEG_BODY':('END_BODY',BODY),
+ 'BEG_PAREN':('END_PAREN',GROUP),
+ 'BEG_ANNO':('END_ANNO',ANNOTATION)}
+
+TAGS = { ONE: 'group',
+ SOME: 'oneOrMore',
+ MAYBE: 'optional',
+ ANY: 'zeroOrMore'}
+
+DEFAULT_NAMESPACE = None
+DATATYPE_LIB = [0, '"http://www.w3.org/2001/XMLSchema-datatypes"']
+OTHER_NAMESPACE = {}
+CONTEXT_FREE = 0
+
+try: enumerate
+except: enumerate = lambda seq: zip(range(len(seq)),seq)
+nodetypes = lambda nl: tuple(map(lambda n: n.type, nl))
+toNodes = lambda toks: map(lambda t: Node(t.type, t.value), toks)
+
+class Node(object):
+ __slots__ = ('type','value','name','quant')
+ def __iter__(self): yield self
+ __len__ = lambda self: 1
+
+ def __init__(self, type='', value=[], name=None, quant=ONE):
+ self.type = type
+ self.value = value
+ self.name = name
+ self.quant = quant
+
+ def format(self, indent=0):
+ out = [' '*indent+repr(self)]
+ write = out.append
+ if isinstance(self.value, str):
+ if self.type==COMMENT:
+ write(' '*(1+indent)+self.value)
+ else:
+ for node in self.value:
+ write(node.format(indent+1))
+ return '\n'.join(out)
+
+ def prettyprint(self):
+ print self.format()
+
+ def toxml(self):
+ if CONTEXT_FREE:
+ out = []
+ write = out.append
+ write('<?xml version="1.0" encoding="UTF-8"?>')
+ write('<grammar>')
+ self.type = None
+ write(self.xmlnode(1))
+ write('</grammar>')
+ return self.add_ns('\n'.join(out))
+ else:
+ return self.add_ns(self.xmlnode())
+
+
+ def xmlnode(self, indent=0):
+ out = []
+ write = out.append
+ if self.type == ROOT:
+ write('<?xml version="1.0" encoding="UTF-8"?>')
+
+ for x in self.value:
+ if not isinstance(x, Node):
+ raise TypeError, "Unhappy Node.value: "+repr(x)
+ elif x.type == START:
+ startelem = '<start><ref name="%s"/></start>' % x.value
+ write(' '*indent+startelem)
+ elif x.type == DEFINE:
+ write(' '*indent+'<define name="%s">' % x.name)
+ write(x.xmlnode(indent+1))
+ write(' '*indent+'</define>')
+ elif x.type == NAME:
+ write(' '*indent+ '<ref name="%s"/>' % x.value)
+ elif x.type == COMMENT:
+ write(' '*indent+'<!-- %s -->' % x.value)
+ elif x.type == LITERAL:
+ write(' '*indent+'<value>%s</value>' % x.value)
+ elif x.type == ANNOTATION:
+ write(' '*indent+\
+ '<a:documentation>%s</a:documentation>' % x.value)
+ elif x.type == INTERLEAVE:
+ write(' '*indent+'<interleave>')
+ write(x.xmlnode(indent+1))
+ write(' '*indent+'</interleave>')
+ elif x.type == CHOICE:
+ write(' '*indent+'<choice>')
+ write(x.xmlnode(indent+1))
+ write(' '*indent+'</choice>')
+ elif x.type == GROUP:
+ write(x.xmlnode(indent))
+ elif x.type == TEXT:
+ write(' '*indent+'<text/>')
+ elif x.type == EMPTY:
+ write(' '*indent+'<empty/>')
+ elif x.type == DATATAG:
+ DATATYPE_LIB[0] = 1 # Use datatypes
+ if x.name is None: # no paramaters
+ write(' '*indent+'<data type="%s"/>' % x.value)
+ else:
+ write(' '*indent+'<data type="%s">' % x.name)
+ p = '<param name="pattern">%s</param>' % x.value
+ write(' '*(indent+1)+p)
+ write(' '*indent+'</data>')
+ elif x.type == ELEM:
+ if x.quant == ONE:
+ write(' '*indent+'<element name="%s">' % x.name)
+ write(x.xmlnode(indent+1))
+ write(' '*indent+'</element>')
+ else:
+ write(' '*indent+'<%s>' % TAGS[x.quant])
+ write(' '*(indent+1)+'<element name="%s">' % x.name)
+ write(x.xmlnode(indent+2))
+ write(' '*(indent+1)+'</element>')
+ write(' '*indent+'</%s>' % TAGS[x.quant])
+ elif x.type == ATTR:
+ if x.value[0].type == TEXT:
+ write(' '*indent+'<attribute name="%s"/>' % x.name)
+ elif x.value[0].type == EMPTY:
+ write(' '*indent+'<attribute name="%s">' % x.name)
+ write(' '*(indent+1)+'<empty/>')
+ write(' '*indent+'</attribute>')
+
+ return '\n'.join(out)
+
+ def __repr__(self):
+ return "Node(%s,%s,%s)[%d]" % (self.type, self.name,
+ self.quant, len(self.value))
+
+ def add_ns(self, xml):
+ "Add namespace attributes to top level element"
+ lines = xml.split('\n')
+ self.nest_annotations(lines) # annots not allowed before root elem
+ for i, line in enumerate(lines):
+ ltpos = line.find('<')
+ if ltpos >= 0 and line[ltpos+1] not in ('!','?'):
+ # We've got an element tag, not PI or comment
+ new = line[:line.find('>')]
+ new += ' xmlns="http://relaxng.org/ns/structure/1.0"'
+ if DEFAULT_NAMESPACE is not None:
+ new += '\n ns=%s' % DEFAULT_NAMESPACE
+ if DATATYPE_LIB[0]:
+ new += '\n datatypeLibrary=%s' % DATATYPE_LIB[1]
+ for ns, url in OTHER_NAMESPACE.items():
+ new += '\n xmlns:%s=%s' % (ns, url)
+ new += '>'
+ lines[i] = new
+ break
+ return '\n'.join(lines)
+
+ def nest_annotations(self, lines):
+ "Nest any top annotation within first element"
+ top_annotations = []
+ for i, line in enumerate(lines[:]):
+ if line.find('<a:') >= 0:
+ top_annotations.append(line)
+ del lines[i]
+ else:
+ ltpos = line.find('<')
+ if ltpos >= 0 and line[ltpos+1] not in ('!','?'):
+ break
+ for line in top_annotations:
+ lines.insert(i, ' '+line)
+
+def findmatch(beg, nodes, offset):
+ level = 1
+ end = PAIRS[beg][0]
+ for i,t in enumerate(nodes[offset:]):
+ if t.type == beg: level += 1
+ elif t.type == end: level -= 1
+ if level == 0:
+ return i+offset
+ raise EOFError, ("No closing token encountered for %s @ %d"
+ % (beg,offset))
+
+def match_pairs(nodes):
+ newnodes = []
+ i = 0
+ while 1:
+ if i >= len(nodes): break
+ node = nodes[i]
+ if node.type in PAIRS.keys():
+ # Look for enclosing brackets
+ match = findmatch(node.type, nodes, i+1)
+ matchtype = PAIRS[node.type][1]
+ node = Node(type=matchtype, value=nodes[i+1:match])
+ node.value = match_pairs(node.value)
+ newnodes.append(node)
+ i = match+1
+ else:
+ newnodes.append(node)
+ i += 1
+ if i >= len(nodes): break
+ if nodes[i].type in (ANY, SOME, MAYBE):
+ newnodes[-1].quant = nodes[i].type
+ i += 1
+ nodes[:] = newnodes
+ return nodes
+
+def type_bodies(nodes):
+ newnodes = []
+ i = 0
+ while 1:
+ if i >= len(nodes): break
+ if nodetypes(nodes[i:i+3]) == (ELEM, NAME, BODY) or \
+ nodetypes(nodes[i:i+3]) == (ATTR, NAME, BODY):
+ name, body = nodes[i+1].value, nodes[i+2]
+ value, quant = type_bodies(body.value), body.quant
+ node = Node(nodes[i].type, value, name, quant)
+ newnodes.append(node)
+ i += 3
+ elif nodetypes(nodes[i:i+2]) == (DATATAG, PATTERN):
+ node = Node(DATATAG, nodes[i+1].value, nodes[i].value)
+ newnodes.append(node)
+ i += 2
+ elif nodes[i] == DEFINE:
+ print nodes[i:]
+ else:
+ if nodes[i].type == GROUP: # Recurse into groups
+ value = type_bodies(nodes[i].value)
+ nodes[i] = Node(GROUP, value, None, nodes[i].quant)
+ newnodes.append(nodes[i])
+ i += 1
+ nodes[:] = newnodes
+ return nodes
+
+def nest_defines(nodes):
+ "Attach groups to named patterns"
+ newnodes = []
+ i = 0
+ while 1:
+ if i >= len(nodes): break
+ node = nodes[i]
+ newnodes.append(node)
+ if node.type == DEFINE:
+ group = []
+ while (i+1) < len(nodes) and nodes[i+1].type <> DEFINE:
+ group.append(nodes[i+1])
+ i += 1
+ node.name = node.value
+ node.value = Node(GROUP, group)
+ i += 1
+ nodes[:] = newnodes
+ return nodes
+
+def intersperse(nodes):
+ "Look for interleaved, choice, or sequential nodes in groups/bodies"
+ for node in nodes:
+ if node.type in (ELEM, ATTR, GROUP, LITERAL):
+ val = node.value
+ ntypes = [n.type for n in val if not isinstance(val,str)]
+ inters = [t for t in ntypes if t in (INTERLEAVE,CHOICE,SEQ)]
+ inters = dict(zip(inters,[0]*len(inters)))
+ if len(inters) > 1:
+ raise ParseError, "Ambiguity in sequencing: %s" % node
+ if len(inters) > 0:
+ intertype = inters.keys()[0]
+ items = []
+ for pat in node.value:
+ if pat.type <> intertype:
+ items.append(pat)
+ node.value = Node(intertype, items)
+ if not isinstance(node.value, str): # No recurse to terminal str
+ intersperse(node.value)
+ return nodes
+
+def scan_NS(nodes):
+ "Look for any namespace configuration lines"
+ global DEFAULT_NAMESPACE, OTHER_NAMESPACE, CONTEXT_FREE
+ for node in nodes:
+ if node.type == DEFAULT_NS:
+ DEFAULT_NAMESPACE = node.value
+ elif node.type == NS:
+ ns, url = map(str.strip, node.value.split('='))
+ OTHER_NAMESPACE[ns] = url
+ elif node.type == ANNOTATION and not OTHER_NAMESPACE.has_key('a'):
+ OTHER_NAMESPACE['a'] =\
+ '"http://relaxng.org/ns/compatibility/annotations/1.0"'
+ elif node.type == DATATYPES:
+ DATATYPE_LIB[:] = [1, node.value]
+ elif node.type == START:
+ CONTEXT_FREE = 1
+
+def make_nodetree(tokens):
+ nodes = toNodes(tokens)
+ match_pairs(nodes)
+ type_bodies(nodes)
+ nest_defines(nodes)
+ intersperse(nodes)
+ scan_NS(nodes)
+ root = Node(ROOT, nodes)
+ return root
+
+if __name__=='__main__':
+ make_nodetree(token_list(sys.stdin.read())).prettyprint()
+
diff --git a/spectest.xml b/spectest.xml
new file mode 100644
index 0000000..18afb2e
--- /dev/null
+++ b/spectest.xml
@@ -0,0 +1,6845 @@
+<!DOCTYPE testSuite [
+<!ENTITY dii "<&#xE14;&#xE35;/>">
+]>
+<testSuite>
+<author>James Clark</author>
+<email>jjc@jclark.com</email>
+<documentation>For October 26 version of the spec.</documentation>
+<testSuite>
+<section>3</section>
+<testSuite>
+<documentation>Various possible syntax errors.</documentation>
+<testCase>
+<section>3</section>
+<incorrect>
+<thisIsJunk/>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <empty/>
+ </element>
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <define name="bar">
+ <text/>
+ </define>
+ <text/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <name>foo</name>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <group>
+ <name>bar</name>
+ </group>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName>
+ <except>
+ <name>foo</name>
+ </except>
+ <except>
+ <name>bar</name>
+ </except>
+ </anyName>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName>
+ <except>
+ <name>foo</name>
+ </except>
+ <except>
+ <name>bar</name>
+ </except>
+ </nsName>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <data type="token">
+ <except>
+ <value>foo</value>
+ </except>
+ <except>
+ <value>bar</value>
+ </except>
+ </data>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty name="bar"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo" extra="bar">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty>
+ <empty/>
+ </empty>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <text>
+ <empty/>
+ </text>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <choice>
+ <text/>
+ <notAllowed>
+ <empty/>
+ </notAllowed>
+ </choice>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo">
+ <empty/>
+ </ref>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <grammar>
+ <start>
+ <parentRef name="foo">
+ <empty/>
+ </parentRef>
+ </start>
+ </grammar>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Tests for obsolete syntax</documentation>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo" ns="http://www.example.com">
+ <attribute name="bar" global="true">
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <not>
+ <name>foo</name>
+ </not>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <difference>
+ <anyName/>
+ <name>foo</name>
+ </difference>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <data type="token" key="foo"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <data type="token" keyRef="foo"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <keyRef name="foo">
+ <data type="token"/>
+ </keyRef>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <key name="foo">
+ <data type="token"/>
+ </key>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Tests for missing attributes and child elements</documentation>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>foo</name>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <zeroOrMore/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <mixed/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice/>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName>
+ <except/>
+ </anyName>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName ns="">
+ <except/>
+ </nsName>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string">
+ <except/>
+ </data>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string">
+ <param/>
+ </data>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <grammar>
+ <start/>
+ </grammar>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="bar">
+ <empty/>
+ </element>
+ </start>
+ <define name="baz"/>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <externalRef/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include/>
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define>
+ <element name="bar">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref/>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <grammar>
+ <start>
+ <parentRef/>
+ </start>
+ </grammar>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Checking of ns attribute</documentation>
+<testCase>
+<section>3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" ns="">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>No checking of ns attribute is performed</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" ns="DAV:">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo xmlns="DAV:"/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>No checking of ns attribute is performed</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" ns="xyzzy">
+ <empty/>
+</element>
+</correct>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>No checking of ns attribute is performed</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" ns="bad_scheme://">
+ <empty/>
+</element>
+</correct>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Checking of datatypeLibrary attribute</documentation>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="foo_bar:xyzzy">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="foobar:xyzzy">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http:ok">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="foo:">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.example.com/%">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.example.com/%xx">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must conform to RFC 2396</documentation>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.example.com/%Aa">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not be relative</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="xyzzy">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not be relative</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="xyzzy#foo:bar">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not be relative</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="xyzzy?foo:bar">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not be relative</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="xyzzy/foo:bar">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="foo:bar">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data datatypeLibrary="" type="string"/>
+</element>
+</correct>
+<valid>
+<foo>x</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not contain fragment identifier</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.example.com#xyzzy">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<documentation>Value of datatypeLibrary attribute must not contain fragment identifier</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.example.com#">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Tests for QName and NCNames in schemas</documentation>
+<testCase>
+<section>3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="&#xE14;&#xE35;">
+ <empty/>
+ </element>
+</element>
+</correct>
+<valid>
+<foo>&dii;</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="&#xE35;" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>&#xE35;</name>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="&#xE35;"/>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="&#xE35;"/>
+ </start>
+ <define name="&#xE35;">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="&#xE14;&#xE35;"/>
+ </start>
+ <define name="&#xE14;&#xE35;">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name=""/>
+ </start>
+ <define name="">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="x y"/>
+ </start>
+ <define name="x y">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+ xmlns:x="http://www.example.com/x">
+ <start>
+ <ref name="x:y"/>
+ </start>
+ <define name="x:y">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0"
+ xmlns:x="http://www.example.com/x"
+ name="x:&#xE35;">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0"
+ xmlns:x="http://www.example.com/x"
+ name="x:y:z">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0"
+ xmlns:x="http://www.example.com/x"
+ name="x:">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Tests for elements that allow only a single pattern child.</documentation>
+<testCase>
+<section>3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ <empty/>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <attribute name="bar">
+ <text/>
+ <empty/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <attribute>
+ <name>bar</name>
+ <text/>
+ <empty/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Tests for foreign element and attribute handling.</documentation>
+<testCase>
+<section>3</section>
+<incorrect>
+<r:element name="foo" xmlns:r="http://relaxng.org/ns/structure/1.0" r:a="val">
+ <r:empty/>
+</r:element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>foo<eg:comment xmlns:eg="http://www.example.com"/></name>
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <value>foo<eg:comment xmlns:eg="http://www.example.com"/></value>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <data type="string"><eg:comment xmlns:eg="http://www.example.com"/></data>
+</element>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty>
+ <ext xmlns="http://www.example.com">
+ <element xmlns="http://relaxng.org/ns/structure/1.0"/>
+ </ext>
+ </empty>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:eg="http://www.example.com">
+ <eg:comment/>
+ <eg:comment/>
+ <start>
+ <eg:comment/>
+ <element>
+ <eg:comment/>
+ <eg:comment/>
+ <name>foo</name>
+ <eg:comment/>
+ <data type="string"/>
+ <eg:comment/>
+ <empty>
+ <eg:comment/>
+ <eg:comment/>
+ </empty>
+ <eg:comment/>
+ <eg:comment/>
+ </element>
+ <eg:comment/>
+ </start>
+ <eg:comment/>
+</grammar>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" xmlns:eg="http://www.example.com"
+ eg:comment="">
+ <start eg:comment="">
+ <element eg:comment="">
+ <name eg:comment="">foo</name>
+ <data eg:comment="" type="string"/>
+ <empty eg:comment=""/>
+ </element>
+ </start>
+</grammar>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0" xmlns="http://www.example.com">
+ <comment/>
+ <comment/>
+ <rng:start>
+ <comment/>
+ <rng:element>
+ <comment/>
+ <comment/>
+ <rng:name>foo</rng:name>
+ <comment/>
+ <rng:data type="string"/>
+ <comment/>
+ </rng:element>
+ <comment/>
+ </rng:start>
+ <comment/>
+</rng:grammar>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+<testCase>
+<section>3</section>
+<correct>
+<rng:grammar xmlns:rng="http://relaxng.org/ns/structure/1.0">
+ <comment/>
+ <comment/>
+ <rng:start>
+ <comment/>
+ <rng:element>
+ <comment/>
+ <comment/>
+ <rng:name>foo</rng:name>
+ <comment/>
+ <rng:data type="string"/>
+ <comment/>
+ </rng:element>
+ <comment/>
+ </rng:start>
+ <comment/>
+</rng:grammar>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+</testSuite>
+</testSuite>
+<testSuite>
+<section>4</section>
+<testSuite>
+<section>4.2</section>
+<testCase>
+<section>4.2</section>
+<correct>
+<element name="&#xA;&#xD;&#x20;&#x9;foo&#xA;&#xD;&#x20;&#x9;" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="&#xA;&#xD;&#x20;&#x9;bar&#xA;&#xD;&#x20;&#x9;"/>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+</testCase>
+<testCase>
+<section>4.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="&#xA;&#xD;&#x20;&#x9;string&#xA;&#xD;&#x20;&#x9;">bar</value>
+</element>
+</correct>
+<valid>
+<foo>bar</foo>
+</valid>
+<invalid>
+<foo>bar </foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="&#xA;&#xD;&#x20;&#x9;string&#xA;&#xD;&#x20;&#x9;"/>
+</element>
+</correct>
+<valid>
+<foo>X</foo>
+</valid>
+</testCase>
+<testCase>
+<section>4.2</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>&#xA;&#xD;&#x20;&#x9;foo&#xA;&#xD;&#x20;&#x9;</name>
+ <attribute><name>&#xA;&#xD;&#x20;&#x9;bar&#xA;&#xD;&#x20;&#x9;</name></attribute>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+</testCase>
+<testCase>
+<section>4.2</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start combine="&#xA;&#xD;&#x20;&#x9;choice&#xA;&#xD;&#x20;&#x9;">
+ <ref name="&#xA;&#xD;&#x20;&#x9;x&#xA;&#xD;&#x20;&#x9;"/>
+ </start>
+ <define name="x">
+ <ref name="y"/>
+ </define>
+ <define name="&#xA;&#xD;&#x20;&#x9;y&#xA;&#xD;&#x20;&#x9;">
+ <grammar>
+ <start combine="&#xA;&#xD;&#x20;&#x9;interleave&#xA;&#xD;&#x20;&#x9;">
+ <parentRef name="&#xA;&#xD;&#x20;&#x9;z&#xA;&#xD;&#x20;&#x9;"/>
+ </start>
+ </grammar>
+ </define>
+ <define name="z">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+</testSuite>
+<testCase>
+<section>4.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value datatypeLibrary="http://www.example.com/this-does-not-exist">bar</value>
+</element>
+</correct>
+<valid>
+<foo>bar</foo>
+</valid>
+<valid>
+<foo>
+ bar
+</foo>
+</valid>
+<valid>
+<foo> bar </foo>
+</valid>
+<invalid>
+<foo>baz</foo>
+</invalid>
+<invalid>
+<foo>ba r</foo>
+</invalid>
+</testCase>
+<testSuite>
+<section>4.5</section>
+<testCase>
+<section>4.5</section>
+<dir name="sub">
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+</dir>
+<correct>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0"
+ xml:base="sub/y" href="x"/>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.5</section>
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="bar">
+ <empty/>
+</element>
+</resource>
+<dir name="sub1">
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="bar">
+ <empty/>
+</element>
+</resource>
+<dir name="sub3">
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+</dir>
+</dir>
+<correct>
+<group xmlns="http://relaxng.org/ns/structure/1.0" xml:base="sub1/">
+ <group>
+ <group xml:base="sub2">
+ <group>
+ <group xml:base="sub3/y">
+ <externalRef href="x"/>
+ </group>
+ </group>
+ </group>
+ </group>
+</group>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.5</section>
+<resource name="x">
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</resource>
+<incorrect>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x#foo"/>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.6</section>
+<testCase>
+<section>4.6</section>
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+<correct>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.6</section>
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+<correct>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x" ns="http://www.example.com"/>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.6</section>
+<resource name="x">
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</resource>
+<incorrect>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.6</section>
+<resource name="x">
+<start xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <empty/>
+ </element>
+</start>
+</resource>
+<incorrect>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.6</section>
+<resource name="x">
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="y"/>
+</resource>
+<resource name="y">
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</resource>
+<incorrect>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="x"/>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.6</section>
+<documentation>Same value of href before resolution, but not a loop.</documentation>
+<dir name="sub">
+<resource name="x">
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="sub/x"/>
+</resource>
+<dir name="sub">
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+</dir>
+</dir>
+<correct>
+<externalRef xmlns="http://relaxng.org/ns/structure/1.0" href="sub/x"/>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.7</section>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x" ns="http://www.example.com"/>
+</grammar>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="y"/>
+</grammar>
+</resource>
+<resource name="y">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="y"/>
+</grammar>
+</resource>
+<resource name="y">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.7</section>
+<dir name="sub">
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="sub/x"/>
+</grammar>
+</resource>
+<dir name="sub">
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+</grammar>
+</resource>
+</dir>
+</dir>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="sub/x"/>
+</grammar>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x">
+ <start>
+ <ref name="foo"/>
+ </start>
+ </include>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+ <start>
+ <ref name="foo"/>
+ </start>
+</grammar>
+</correct>
+<valid><foo/></valid>
+<invalid><bar/></invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+</grammar>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </include>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <include href="x"/>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid><foo/></valid>
+<invalid><bar/></invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="x">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo" combine="choice">
+ <element name="foo3">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</resource>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+ <include href="x">
+ <define name="foo" combine="choice">
+ <element name="foo1">
+ <empty/>
+ </element>
+ </define>
+ </include>
+ <define name="foo">
+ <element name="foo2">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid><foo1/></valid>
+<valid><foo2/></valid>
+<invalid><foo3/></invalid>
+</testCase>
+<testCase>
+<section>4.7</section>
+<resource name="level1.rng">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<include href="level2.rng">
+ <define name="foo">
+ <element name="bar">
+ <empty/>
+ </element>
+ </define>
+</include>
+</grammar>
+</resource>
+<resource name="level2.rng">
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="bar">
+ <element name="bar">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</resource>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <ref name="foo"/>
+</start>
+<include href="level1.rng">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</include>
+</grammar>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.8</section>
+<testCase>
+<section>4.8</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" ns="http://www.example.com" name="foo">
+ <attribute name="bar" ns="http://www.example.com"/>
+</element>
+</correct>
+<valid>
+<eg:foo eg:bar="x" xmlns:eg="http://www.example.com"/>
+</valid>
+<invalid>
+<eg:foo xmlns:eg="http://www.example.com" bar="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.8</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" ns="http://www.example.com" name="foo">
+ <attribute name="bar"/>
+</element>
+</correct>
+<invalid>
+<eg:foo xmlns:eg="http://www.example.com" eg:bar="x"/>
+</invalid>
+<valid>
+<eg:foo xmlns:eg="http://www.example.com" bar="x"/>
+</valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.9</section>
+<testCase>
+<section>4.9</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" ns="http://www.example.com" name="foo">
+ <attribute>
+ <name>bar</name>
+ </attribute>
+</element>
+</correct>
+<valid>
+<eg:foo xmlns:eg="http://www.example.com" eg:bar="x"/>
+</valid>
+<invalid>
+<eg:foo xmlns:eg="http://www.example.com" bar="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.6</section>
+<section>4.9</section>
+<resource name="x">
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <empty/>
+</element>
+</resource>
+<correct>
+<group ns="http://www.example.com" xmlns="http://relaxng.org/ns/structure/1.0" >
+<externalRef href="x"/>
+</group>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<correct>
+<group xmlns="http://relaxng.org/ns/structure/1.0">
+ <element ns="http://www.example.com">
+ <name>foo</name>
+ <empty/>
+ </element>
+</group>
+</correct>
+<valid><foo xmlns="http://www.example.com"/></valid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<correct>
+<element ns="http://www.example.com" xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>foo</name>
+ <empty/>
+</element>
+</correct>
+<valid><foo xmlns="http://www.example.com"/></valid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute ns="http://www.example.com">
+ <name>bar</name>
+ <text/>
+ </attribute>
+</element>
+</correct>
+<valid><foo xmlns:x="http://www.example.com" x:bar="whatever"/></valid>
+<invalid><foo bar="whatever"/></invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.10</section>
+<testCase>
+<section>4.10</section>
+<incorrect>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo:bar">
+ <empty/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.10</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="eg:foo" xmlns:eg="http://www.example.com">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo xmlns="http://www.example.com/"/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.10</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo" xmlns:eg="http://www.example.com">
+ <attribute name="eg:bar"/>
+</element>
+</correct>
+<valid>
+<foo xmlns:ex="http://www.example.com" ex:bar="x"/>
+</valid>
+<invalid>
+<foo xmlns:ex="http://www.example.com/" ex:bar="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.10</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <attribute name="xml:lang"/>
+</element>
+</correct>
+<valid>
+<foo xml:lang="en"/>
+</valid>
+<invalid>
+<foo lang="en"/>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.11</section>
+<testCase>
+<section>4.11</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <div ns="http://www.example.com">
+ <div>
+ <start>
+ <ref name="foo"/>
+ </start>
+ </div>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </div>
+ <div/>
+</grammar>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<testCase>
+<section>4.12</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+
+<start>
+ <element name="foo">
+ <ref name="bars"/>
+ </element>
+</start>
+
+<define name="bars">
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+</define>
+
+</grammar>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo></foo>
+</invalid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo></foo>
+</invalid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<section>4.15</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <zeroOrMore>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </zeroOrMore>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<valid>
+<foo></foo>
+</valid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<section>4.14</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </optional>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<valid>
+<foo></foo>
+</valid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <value>x</value>
+ <value>y</value>
+ <value>z</value>
+ </list>
+</element>
+</correct>
+<valid>
+<foo>x y z</foo>
+</valid>
+<invalid>
+<foo>x</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<section>4.13</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <mixed>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </mixed>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo></foo>
+</invalid>
+<valid>
+<foo><bar/>X<bar/><bar/></foo>
+</valid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name>foo</name>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo></foo>
+</invalid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName>
+ <except>
+ <name>foo</name>
+ <name>bar</name>
+ <name>baz</name>
+ </except>
+ </anyName>
+ <empty/>
+</element>
+</correct>
+<valid><xyzzy/></valid>
+<invalid><foo/></invalid>
+<invalid><bar/></invalid>
+<invalid><baz/></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="token">
+ <except>
+ <value>x</value>
+ <value>y</value>
+ <value>z</value>
+ </except>
+ </data>
+</element>
+</correct>
+<valid><foo/></valid>
+<valid><foo>xyz</foo></valid>
+<invalid><foo>x</foo></invalid>
+<invalid><foo>y</foo></invalid>
+<invalid><foo>y</foo></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+<valid>
+<foo bar="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name>bar</name>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+<valid>
+<foo bar="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo></foo>
+</invalid>
+<invalid>
+<foo>X</foo>
+</invalid>
+<invalid>
+<foo><bar/>X<bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <element name="bar1">
+ <empty/>
+ </element>
+ <element name="bar2">
+ <empty/>
+ </element>
+ <element name="bar3">
+ <empty/>
+ </element>
+ </choice>
+</element>
+</correct>
+<valid><foo><bar1/></foo></valid>
+<valid><foo><bar2/></foo></valid>
+<valid><foo><bar3/></foo></valid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar1">
+ <empty/>
+ </element>
+ <element name="bar2">
+ <empty/>
+ </element>
+ <element name="bar3">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid><foo><bar1/><bar2/><bar3/></foo></valid>
+<valid><foo><bar1/><bar3/><bar2/></foo></valid>
+<valid><foo><bar2/><bar1/><bar3/></foo></valid>
+<valid><foo><bar2/><bar3/><bar1/></foo></valid>
+<valid><foo><bar3/><bar1/><bar2/></foo></valid>
+<valid><foo><bar3/><bar2/><bar1/></foo></valid>
+<invalid><foo><bar2/><bar1/></foo></invalid>
+<invalid><foo><bar1/><bar3/><bar2/><bar1/></foo></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid><foo><bar/></foo></valid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid><foo><bar/></foo></valid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>4.12</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <element name="bar">
+ <empty/>
+ </element>
+ </choice>
+</element>
+</correct>
+<valid><foo><bar/></foo></valid>
+<invalid><foo/></invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.13</section>
+<testCase>
+<section>4.13</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <mixed>
+ <element name="bar">
+ <empty/>
+ </element>
+ </mixed>
+</element>
+</correct>
+<valid><foo>x<bar/></foo></valid>
+<valid><foo><bar/></foo></valid>
+<valid><foo><bar/>x</foo></valid>
+<valid><foo>x<bar/>y</foo></valid>
+<invalid><foo/></invalid>
+<invalid><foo><bar/><bar/></foo></invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.14</section>
+<testCase>
+<section>4.14</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <element name="bar">
+ <empty/>
+ </element>
+ </optional>
+</element>
+</correct>
+<valid><foo><bar/></foo></valid>
+<valid><foo/></valid>
+<invalid><foo>x<bar/></foo></invalid>
+<invalid><foo><bar/><bar/></foo></invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.15</section>
+<testCase>
+<section>4.15</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <zeroOrMore>
+ <element name="bar">
+ <empty/>
+ </element>
+ </zeroOrMore>
+</element>
+</correct>
+<valid><foo><bar/></foo></valid>
+<valid><foo/></valid>
+<invalid><foo>x<bar/></foo></invalid>
+<invalid><foo><baz/></foo></invalid>
+<valid><foo><bar/><bar/></foo></valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.16</section>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <anyName>
+ <except>
+ <anyName/>
+ </except>
+ </anyName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <anyName>
+ <except>
+ <choice>
+ <anyName/>
+ <name>foo</name>
+ </choice>
+ </except>
+ </anyName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <nsName ns="">
+ <except>
+ <nsName ns=""/>
+ </except>
+ </nsName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <nsName ns="">
+ <except>
+ <choice>
+ <nsName ns=""/>
+ <name>foo</name>
+ </choice>
+ </except>
+ </nsName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <nsName ns="">
+ <except>
+ <anyName/>
+ </except>
+ </nsName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element>
+ <nsName ns="">
+ <except>
+ <choice>
+ <anyName/>
+ <name>foo</name>
+ </choice>
+ </except>
+ </nsName>
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<documentation>Tests that 4.16 is before 4.20.</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <zeroOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <anyName/>
+ </except>
+ </anyName>
+ <text/>
+ </attribute>
+ <notAllowed/>
+ </zeroOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<documentation>Tests that 4.16 is before removal of unreachable definitions.</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <empty/>
+ </element>
+</start>
+<define name="bar">
+ <element>
+ <anyName>
+ <except>
+ <anyName/>
+ </except>
+ </anyName>
+ <empty/>
+ </element>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="xmlns">
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<correct>
+<element name="xmlns" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</correct>
+<valid><xmlns/></valid>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name=" xmlns">
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <notAllowed/>
+ <attribute name="xmlns">
+ <text/>
+ </attribute>
+ </optional>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define name="foo">
+ <attribute name="xmlns">
+ <text/>
+ </attribute>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="xmlns" ns="">
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <choice>
+ <name ns="">xmlns</name>
+ <name>foo</name>
+ </choice>
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name ns="">xmlns</name>
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name>xmlns</name>
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name>
+ xmlns
+ </name>
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <choice>
+ <name>foo</name>
+ <name ns="">xmlns</name>
+ </choice>
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <name>xmlns</name>
+ </except>
+ </anyName>
+ <text/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <nsName ns="">
+ <except>
+ <name>xmlns</name>
+ </except>
+ </nsName>
+ <text/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute ns="http://www.w3.org/2000/xmlns" name="bar">
+ <text/>
+ </attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0" ns="http://www.w3.org/2000/xmlns">
+ <empty/>
+</element>
+</correct>
+<valid><foo xmlns="http://www.w3.org/2000/xmlns"/></valid>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="token">
+ <param name="minLength">2</param>
+ </data>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="tok"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="tok"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <notAllowed/>
+ <data type="token">
+ <param name="minLength">2</param>
+ </data>
+ </optional>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <notAllowed/>
+ <data type="tok"/>
+ </optional>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <notAllowed/>
+ <value type="tok"/>
+ </optional>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <empty/>
+ </element>
+</start>
+<define name="foo">
+ <data type="token">
+ <param name="minLength">2</param>
+ </data>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <empty/>
+ </element>
+</start>
+<define name="foo">
+ <data type="tok"/>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.16</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <empty/>
+ </element>
+</start>
+<define name="foo">
+ <value type="tok"/>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.17</section>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <ref name="x"/>
+</start>
+<define name="x">
+ <element name="foo1">
+ <empty/>
+ </element>
+</define>
+<define name="x" combine="choice">
+ <element name="foo2">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="foo3">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start name="x">
+ <element name="foo1">
+ <empty/>
+ </element>
+</start>
+<start name="x" combine="choice">
+ <element name="foo2">
+ <empty/>
+ </element>
+</start>
+<start name="x">
+ <element name="foo3">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <ref name="x"/>
+</start>
+<define name="x">
+ <element name="foo1">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="foo2">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start name="x">
+ <element name="foo1">
+ <empty/>
+ </element>
+</start>
+<start name="x">
+ <element name="foo2">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <ref name="x"/>
+</start>
+<define name="x" combine="choice">
+ <element name="foo1">
+ <empty/>
+ </element>
+</define>
+<define name="x" combine="choice">
+ <element name="foo2">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="foo3">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</correct>
+<valid>
+<foo1/>
+</valid>
+<valid>
+<foo2/>
+</valid>
+<valid>
+<foo3/>
+</valid>
+<invalid>
+<foo4/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.17</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start combine="choice">
+ <element name="foo1">
+ <empty/>
+ </element>
+</start>
+<start combine="choice">
+ <element name="foo2">
+ <empty/>
+ </element>
+</start>
+<start>
+ <element name="foo3">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</correct>
+<valid>
+<foo1/>
+</valid>
+<valid>
+<foo2/>
+</valid>
+<valid>
+<foo3/>
+</valid>
+<invalid>
+<foo4/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <ref name="x"/>
+ </element>
+</start>
+<define name="x" combine="choice">
+ <element name="bar1">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="bar2">
+ <empty/>
+ </element>
+</define>
+<define name="x" combine="interleave">
+ <element name="bar3">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+<grammar>
+<start name="x" combine="choice">
+ <element name="bar1">
+ <empty/>
+ </element>
+</start>
+<start name="x">
+ <element name="bar2">
+ <empty/>
+ </element>
+</start>
+<start name="x" combine="interleave">
+ <element name="bar3">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <ref name="x"/>
+ </element>
+</start>
+<define name="x" combine="interleave">
+ <element name="bar1">
+ <empty/>
+ </element>
+</define>
+<define name="x" combine="interleave">
+ <element name="bar2">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="bar3">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</correct>
+<valid>
+<foo><bar1/><bar2/><bar3/></foo>
+</valid>
+<valid>
+<foo><bar1/><bar3/><bar2/></foo>
+</valid>
+<valid>
+<foo><bar2/><bar3/><bar1/></foo>
+</valid>
+<invalid>
+<foo><bar2/><bar3/><bar1/><bar2/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.17</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+<grammar>
+<start combine="interleave">
+ <element name="bar1">
+ <empty/>
+ </element>
+</start>
+<start>
+ <element name="bar2">
+ <empty/>
+ </element>
+</start>
+<start combine="interleave">
+ <element name="bar3">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</element>
+</correct>
+<valid>
+<foo><bar1/><bar2/><bar3/></foo>
+</valid>
+<valid>
+<foo><bar1/><bar3/><bar2/></foo>
+</valid>
+<valid>
+<foo><bar2/><bar3/><bar1/></foo>
+</valid>
+<invalid>
+<foo><bar2/><bar3/><bar1/><bar2/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <ref name="x"/>
+ </element>
+</start>
+<define name="x">
+ <element name="bar1">
+ <empty/>
+ </element>
+</define>
+<define name="x" combine="interleave">
+ <element name="bar2">
+ <empty/>
+ </element>
+</define>
+<define name="x">
+ <element name="bar3">
+ <empty/>
+ </element>
+</define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.17</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+<grammar>
+<start name="x">
+ <element name="bar1">
+ <empty/>
+ </element>
+</start>
+<start name="x" combine="interleave">
+ <element name="bar2">
+ <empty/>
+ </element>
+</start>
+<start name="x">
+ <element name="bar3">
+ <empty/>
+ </element>
+</start>
+</grammar>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.18</section>
+<testCase>
+<section>4.18</section>
+<documentation>grammar must have a start</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.18</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define name="bar">
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.19</documentation>
+<incorrect>
+<choice xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <notAllowed/>
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </group>
+</choice>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>every ref must have a def</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.18</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define name="foo">
+ <ref name="bar"/>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.19</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <notAllowed/>
+ <ref name="foo"/>
+ </group>
+ </choice>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>every parentRef must have a def</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <parentRef name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.18</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define name="bar">
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <parentRef name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<documentation>4.17 is before 4.19</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <notAllowed/>
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <parentRef name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </group>
+ </choice>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <parentRef name="foo"/>
+ </start>
+ </grammar>
+ </choice>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.18</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="foo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </define>
+</grammar>
+</correct>
+<valid><foo/></valid>
+</testCase>
+<testCase>
+<section>4.18</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <grammar>
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="innerFoo">
+ <parentRef name="foo"/>
+ </element>
+ </define>
+ </grammar>
+ </start>
+ <define name="foo">
+ <element name="outerFoo">
+ <empty/>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid><innerFoo><outerFoo/></innerFoo></valid>
+<invalid><outerFoo/></invalid>
+</testCase>
+<testCase>
+<section>4.18</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="outerFoo">
+ <grammar>
+ <start>
+ <ref name="foo"/>
+ </start>
+ <define name="foo">
+ <element name="innerFoo">
+ <empty/>
+ </element>
+ </define>
+ </grammar>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid><outerFoo><innerFoo/></outerFoo></valid>
+<invalid><innerFoo/></invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>4.19</section>
+<testCase>
+<section>4.19</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <ref name="bar"/>
+ </element>
+ </start>
+ <define name="bar">
+ <optional>
+ <element name="bar">
+ <empty/>
+ </element>
+ <ref name="bar"/>
+ </optional>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>4.19</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <ref name="bar"/>
+ </element>
+ </start>
+ <define name="bar">
+ <element name="bar">
+ <optional>
+ <ref name="bar"/>
+ </optional>
+ </element>
+ </define>
+</grammar>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo><bar><bar/></bar></foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>4.19</section>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <empty/>
+ </element>
+ </start>
+ <define name="bar">
+ <ref name="bar"/>
+ </define>
+</grammar>
+</correct>
+<valid><foo/></valid>
+</testCase>
+<testCase>
+<section>4.19</section>
+<section>4.20</section>
+<documentation>Tests that recursion detection happens before
+normalization of notAllowed.</documentation>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <notAllowed/>
+ <ref name="bar"/>
+ </group>
+ </choice>
+ </start>
+ <define name="bar">
+ <element name="bar">
+ <empty/>
+ </element>
+ <optional>
+ <ref name="bar"/>
+ </optional>
+ </define>
+</grammar>
+</incorrect>
+</testCase>
+</testSuite>
+</testSuite>
+<testSuite>
+<section>6</section>
+<testSuite>
+<section>6.1</section>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName/>
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName>
+ <except>
+ <name ns="">foo</name>
+ </except>
+ </anyName>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<valid>
+<bar/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <anyName>
+ <except>
+ <nsName ns=""/>
+ </except>
+ </anyName>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName ns=""/>
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<foo xmlns="http://www.example.com"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName ns="http://www.example.com"/>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo xmlns="HTTP://www.example.com"/>
+</invalid>
+<invalid>
+<foo xmlns="http://www.example.com/"/>
+</invalid>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName ns="http://www.example.com">
+ <except>
+ <name ns="http://www.example.com">foo</name>
+ </except>
+ </nsName>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo xmlns="http://www.example.com"/>
+</invalid>
+<valid>
+<bar xmlns="http://www.example.com"/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <nsName ns="http://www.example.com">
+ <except>
+ <name ns="">foo</name>
+ </except>
+ </nsName>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<bar/>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<valid>
+<bar xmlns="http://www.example.com"/>
+</valid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name ns="http://www.example.com">foo</name>
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo xmlns="http://www.example.com"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<bar xmlns="http://www.example.com"/>
+</invalid>
+<invalid>
+<foo xmlns="http://www.example.org"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name ns="">foo</name>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<foo xmlns="http://www.example.com"/>
+</invalid>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<bar xmlns="http://www.example.com"/>
+</invalid>
+<invalid>
+<bar/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.1</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <name ns="">foo</name>
+ <name ns="">bar</name>
+ </choice>
+ <empty/>
+</element>
+</correct>
+<invalid>
+<baz/>
+</invalid>
+<valid>
+<foo/>
+</valid>
+<valid>
+<bar/>
+</valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2</section>
+<testSuite>
+<section>6.2.1</section>
+<testCase>
+<section>6.2.1</section>
+<correct>
+<choice xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+</choice>
+</correct>
+<valid>
+<foo/>
+</valid>
+<valid>
+<bar/>
+</valid>
+<invalid>
+<baz/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.1</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <group>
+ <element name="bar1">
+ <empty/>
+ </element>
+ <element name="bar2">
+ <empty/>
+ </element>
+ </group>
+ <group>
+ <element name="bar1">
+ <empty/>
+ </element>
+ <element name="bar3">
+ <empty/>
+ </element>
+ </group>
+ </choice>
+</element>
+</correct>
+<valid>
+<foo><bar1/><bar2/></foo>
+</valid>
+<valid>
+<foo><bar1/><bar3/></foo>
+</valid>
+<invalid>
+<foo><bar1/></foo>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar2/></foo>
+</invalid>
+<invalid>
+<foo><bar3/></foo>
+</invalid>
+<invalid>
+<foo><bar1/><bar2/><bar3/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.1</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <group>
+ <attribute name="bar1">
+ <text/>
+ </attribute>
+ <attribute name="bar2">
+ <text/>
+ </attribute>
+ </group>
+ <group>
+ <attribute name="bar1">
+ <text/>
+ </attribute>
+ <attribute name="bar3">
+ <text/>
+ </attribute>
+ </group>
+ </choice>
+</element>
+</correct>
+<valid>
+<foo bar1="x" bar2="x"/>
+</valid>
+<valid>
+<foo bar1="x" bar3="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo bar1="x"/>
+</invalid>
+<invalid>
+<foo bar2="x"/>
+</invalid>
+<invalid>
+<foo bar3="x"/>
+</invalid>
+<invalid>
+<foo bar1="x" bar2="x" bar3="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.1</section>
+<correct>
+<choice xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <element name="bar">
+ <empty/>
+ </element>
+ </element>
+ <element name="foo">
+ <element name="baz">
+ <empty/>
+ </element>
+ </element>
+</choice>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo><baz/></foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo><foo/></foo>
+</invalid>
+<invalid>
+<bar/>
+</invalid>
+<invalid>
+<fobaz/>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.2</section>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="baz">
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+<invalid>
+<foo><baz/><bar/></foo>
+</invalid>
+<invalid>
+<foo><bar/><baz/><bar/><baz/></foo>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo><baz/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ <attribute name="baz">
+ <text/>
+ </attribute>
+ </group>
+</element>
+</correct>
+<valid>
+<foo bar="x" baz="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ <attribute name="baz">
+ <text/>
+ </attribute>
+ </group>
+</element>
+</correct>
+<valid>
+<foo bar="x" baz="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+<invalid>
+<foo baz="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <attribute name="baz">
+ <text/>
+ </attribute>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ </group>
+</element>
+</correct>
+<valid>
+<foo bar="x" baz="x"/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+<invalid>
+<foo baz="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ <element name="baz">
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid>
+<foo bar="x"><baz/></foo>
+</valid>
+<invalid>
+<foo><baz/></foo>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+<invalid>
+<foo baz="x"><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.2</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="baz">
+ <empty/>
+ </element>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ </group>
+</element>
+</correct>
+<valid>
+<foo bar="x"><baz/></foo>
+</valid>
+<invalid>
+<foo><baz/></foo>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+<invalid>
+<foo baz="x"><bar/></foo>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.3</section>
+<testCase>
+<section>6.2.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <empty/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+<valid>
+<foo> </foo>
+</valid>
+<valid>
+<foo>
+
+
+</foo>
+</valid>
+<valid>
+<foo>
+<?target data?>
+<?target data?>
+<?target data?>
+<?target data?>
+</foo>
+</valid>
+<invalid>
+<foo>x</foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar">
+ <empty/>
+ </attribute>
+</element>
+</correct>
+<valid><foo bar=""/></valid>
+<valid><foo bar=" "/></valid>
+<invalid><foo bar="x"/></invalid>
+</testCase>
+<testCase>
+<section>6.2.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <empty/>
+ </list>
+</element>
+</correct>
+<valid><foo/></valid>
+<valid><foo> </foo></valid>
+<invalid><foo>x</foo></invalid>
+<invalid><foo><bar/></foo></invalid>
+<invalid><foo bar=""/></invalid>
+</testCase>
+<testCase>
+<section>6.2.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar">
+ <list>
+ <empty/>
+ </list>
+ </attribute>
+</element>
+</correct>
+<valid><foo bar=""/></valid>
+<valid><foo bar=" "/></valid>
+<invalid><foo bar="x"/></invalid>
+</testCase>
+<testCase>
+<section>6.2.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ <choice>
+ <empty/>
+ <element name="baz">
+ <empty/>
+ </element>
+ </choice>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+<valid>
+<foo><bar/></foo>
+</valid>
+<invalid>
+<foo></foo>
+</invalid>
+<invalid>
+<foo><bar/><baz/><baz/></foo>
+</invalid>
+</testCase>
+<testCase>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <empty/>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ </choice>
+</element>
+</correct>
+<valid>
+<foo bar="x"/>
+</valid>
+<valid>
+<foo/>
+</valid>
+<invalid>
+<foo baz="x"/>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.4</section>
+<testCase>
+<section>6.2.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <text/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+<valid>
+<foo> </foo>
+</valid>
+<valid>
+<foo>x</foo>
+</valid>
+<valid>
+<foo>
+x
+<?target data?>
+y
+</foo>
+</valid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <text/>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+</foo>
+</valid>
+<valid>
+<foo>
+x
+<bar/>
+</foo>
+</valid>
+<valid>
+<foo>
+x
+<?target data?>
+y
+<bar/></foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar/>x</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ <text/>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+</foo>
+</valid>
+<invalid>
+<foo>
+x
+<bar/>
+</foo>
+</invalid>
+<valid>
+<foo>
+<bar/>
+x
+<?target data?>
+y
+</foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo><bar/>x</foo>
+</valid>
+</testCase>
+<testCase>
+<section>6.2.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <text/>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+</foo>
+</valid>
+<valid>
+<foo>
+x
+<bar/>
+</foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+x
+<?target data?>
+y
+</foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo><bar/>x</foo>
+</valid>
+<valid>
+<foo>x<bar/>x</foo>
+</valid>
+<invalid>
+<foo>x<bar/>x<bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar">
+ <text/>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+<valid>
+<foo bar="x"/>
+</valid>
+<valid>
+<foo bar=" "/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar/>x<bar/></foo>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.5</section>
+<testCase>
+<section>6.2.5</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <element name="bar">
+ <empty/>
+ </element>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.5</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <group>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/><bar/><bar/><bar/><bar/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo><bar/><bar/><bar/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.5</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <nsName ns=""/>
+ <text/>
+ </attribute>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo x=""/>
+</valid>
+<valid>
+<foo x="" y=""/>
+</valid>
+<valid>
+<foo x="" y="" z=""/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo xmlns:ns="http://www.example.com" ns:x=""/>
+</invalid>
+<invalid>
+<foo x="" xmlns:ns="http://www.example.com" ns:x=""/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.5</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <choice>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ <element name="bar">
+ <text/>
+ </element>
+ </choice>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo bar=""><bar/><bar/></foo>
+</valid>
+<valid>
+<foo><bar/></foo>
+</valid>
+<valid>
+<foo bar=""/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.6</section>
+<testCase>
+<section>6.2.6</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="baz">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+<valid>
+<foo><baz/><bar/></foo>
+</valid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo><baz/></foo>
+</invalid>
+<invalid>
+<foo><bar/><bar/></foo>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.6</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <group>
+ <element name="bar1">
+ <empty/>
+ </element>
+ <element name="bar2">
+ <empty/>
+ </element>
+ </group>
+ <element name="baz">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo><baz/><bar1/><bar2/></foo>
+</valid>
+<valid>
+<foo><bar1/><baz/><bar2/></foo>
+</valid>
+<valid>
+<foo><bar1/><bar2/><baz/></foo>
+</valid>
+<invalid>
+<foo><baz/><bar2/><bar1/></foo>
+</invalid>
+<invalid>
+<foo><bar2/><bar1/></foo>
+</invalid>
+<invalid>
+<foo><baz/><bar2/><bar1/></foo>
+</invalid>
+<invalid>
+<foo><baz/><bar1/></foo>
+</invalid>
+<invalid>
+<foo><baz/><bar2/></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.6</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <attribute name="bar">
+ <text/>
+ </attribute>
+ <attribute name="baz">
+ <text/>
+ </attribute>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo bar="" baz=""/>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo bar=""/>
+</invalid>
+<invalid>
+<foo baz=""/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.6</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <attribute name="baz">
+ <text/>
+ </attribute>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo baz=""><bar/></foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo bar=""/>
+</invalid>
+<invalid>
+<foo bar=""><baz/><baz/></foo>
+</invalid>
+<invalid>
+<foo><baz/><baz/></foo>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.7</section>
+<testCase>
+<section>6.2.7</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name ns="">bar</name>
+ <value type="string" datatypeLibrary="">baz</value>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar="baz"/>
+</valid>
+<invalid>
+<foo bar=" baz"/>
+</invalid>
+<invalid>
+<foo bar="b"/>
+</invalid>
+<invalid>
+<foo bar=""/>
+</invalid>
+<invalid>
+<foo bar=" "/>
+</invalid>
+<invalid>
+<foo><bar>baz</bar></foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name ns="">bar</name>
+ <choice>
+ <value type="string" datatypeLibrary="">baz</value>
+ <empty/>
+ </choice>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar="baz"/>
+</valid>
+<valid>
+<foo bar=""/>
+</valid>
+<invalid>
+<foo bar=" baz"/>
+</invalid>
+<invalid>
+<foo bar="b"/>
+</invalid>
+<invalid>
+<foo><bar>baz</bar></foo>
+</invalid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute>
+ <name ns="">bar</name>
+ <value type="string"/>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar=""/>
+</valid>
+<invalid>
+<foo bar=" "/>
+</invalid>
+<invalid>
+<foo bar="x"/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0">
+ <name ns="">foo</name>
+ <group>
+ <element>
+ <name ns="">bar</name>
+ <empty/>
+ </element>
+ <element>
+ <name ns="">baz</name>
+ <empty/>
+ </element>
+ </group>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+<baz/>
+</foo>
+</valid>
+<valid>
+<foo>
+<bar/>
+&#xD;
+<baz/>
+</foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<bar><bar/><baz/></bar>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="string"/>
+</element>
+</correct>
+<valid><foo/></valid>
+<invalid><foo> </foo></invalid>
+<invalid><foo>x</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <value type="string"/>
+ <empty/>
+ </choice>
+</element>
+</correct>
+<valid><foo/></valid>
+<valid><foo> </foo></valid>
+<invalid><foo>x</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <data type="token"/>
+ </list>
+</element>
+</correct>
+<invalid><foo/></invalid>
+<invalid><foo> </foo></invalid>
+<valid><foo>x</foo></valid>
+<valid><foo> x </foo></valid>
+<invalid><foo>x y</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<requires datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <param name="minLength">2</param>
+ </data>
+</element>
+</correct>
+<valid><foo>xx</foo></valid>
+<valid><foo>xxx</foo></valid>
+<valid><foo> </foo></valid>
+<valid><foo> </foo></valid>
+<invalid><foo>x</foo></invalid>
+<invalid><foo> </foo></invalid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <value>x</value>
+ <element name="bar">
+ <empty/>
+ </element>
+ </choice>
+</element>
+</correct>
+<valid><foo> x </foo></valid>
+<valid><foo>x</foo></valid>
+<invalid><foo>y</foo></invalid>
+<valid><foo><bar/></foo></valid>
+<valid>
+<foo>
+<bar/>
+</foo>
+</valid>
+<invalid><foo>x<bar/></foo></invalid>
+<invalid><foo/></invalid>
+<invalid><foo><bar/>x</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.7</section>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <value>x</value>
+ <mixed>
+ <element name="bar">
+ <empty/>
+ </element>
+ </mixed>
+ </choice>
+</element>
+</correct>
+<valid><foo> x </foo></valid>
+<valid><foo>x</foo></valid>
+<invalid><foo>y</foo></invalid>
+<valid><foo><bar/></foo></valid>
+<valid>
+<foo>
+<bar/>
+</foo>
+</valid>
+<valid><foo>x<bar/></foo></valid>
+<invalid><foo/></invalid>
+<valid><foo><bar/>x</foo></valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.8</section>
+<testCase>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string">
+ <except>
+ <choice>
+ <value>x</value>
+ <value>y</value>
+ </choice>
+ </except>
+ </data>
+</element>
+</correct>
+<valid>
+<foo>xyzzy</foo>
+</valid>
+<invalid>
+<foo>x</foo>
+</invalid>
+<invalid>
+<foo>y</foo>
+</invalid>
+<invalid>
+<foo> x</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string"/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value/>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>6.2.8</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string">
+ <except>
+ <value/>
+ </except>
+ </data>
+</element>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+<valid>
+<foo>x</foo>
+</valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.9</section>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string" datatypeLibrary=""/>
+</element>
+</correct>
+<valid>
+<foo>xyzzy</foo>
+</valid>
+<valid>
+<foo>
+x
+<?target data?>
+y
+<?target data?>
+z
+</foo>
+</valid>
+<valid>
+<foo></foo>
+</valid>
+<valid>
+<foo>
+</foo>
+</valid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo bar=""/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="token" datatypeLibrary=""/>
+</element>
+</correct>
+<valid>
+<foo>xyzzy</foo>
+</valid>
+<valid>
+<foo>
+x
+<?target data?>
+y
+<?target data?>
+z
+</foo>
+</valid>
+<valid>
+<foo></foo>
+</valid>
+<valid>
+<foo>
+</foo>
+</valid>
+<invalid>
+<foo><bar/></foo>
+</invalid>
+<invalid>
+<foo bar=""/>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="string" datatypeLibrary="">x</value>
+</element>
+</correct>
+<valid><foo>x</foo></valid>
+<invalid><foo>xy</foo></invalid>
+<invalid><foo> x</foo></invalid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="string" datatypeLibrary=""> x</value>
+</element>
+</correct>
+<valid><foo> x</foo></valid>
+<invalid><foo> xy</foo></invalid>
+<invalid><foo>x</foo></invalid>
+<invalid><foo/></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="token" datatypeLibrary="">x</value>
+</element>
+</correct>
+<valid><foo>x</foo></valid>
+<valid><foo> x</foo></valid>
+<valid><foo>x </foo></valid>
+<valid><foo>&#xA;&#xD;&#x9;&#x20;x&#xA;&#xD;&#x9;&#x20;</foo></valid>
+<invalid><foo/></invalid>
+<invalid><foo>xy</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="token" datatypeLibrary="">x y</value>
+</element>
+</correct>
+<valid><foo>x y</foo></valid>
+<valid><foo> x y </foo></valid>
+<valid><foo>x&#xA;&#xD;&#x9;&#x20;y</foo></valid>
+<invalid><foo>xy</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="token" datatypeLibrary="">&#xA;&#xD;&#x9;&#x20;x&#xA;&#xD;&#x9;&#x20;</value>
+</element>
+</correct>
+<valid><foo>x</foo></valid>
+<valid><foo> x</foo></valid>
+<valid><foo>x </foo></valid>
+<valid><foo>&#xD;&#x9;x&#x20;&#xA;</foo></valid>
+<invalid><foo/></invalid>
+<invalid><foo>xy</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="token" datatypeLibrary="">x&#xA;&#xD;&#x9;&#x20;y</value>
+</element>
+</correct>
+<valid><foo>x y</foo></valid>
+<valid><foo>x y</foo></valid>
+<valid><foo> x y </foo></valid>
+<valid><foo>x&#xD;&#x9;y</foo></valid>
+<valid><foo>x&#x20;&#xA;y</foo></valid>
+<invalid><foo/></invalid>
+<invalid><foo>xy</foo></invalid>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="decimal" datatypeLibrary=""/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <value type="decimal" datatypeLibrary=""/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="string" datatypeLibrary="">
+ <param name="length">2</param>
+ </data>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>6.2.9</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <data type="token" datatypeLibrary="">
+ <param name="length">2</param>
+ </data>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>6.2.10</section>
+<testCase>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <value type="string">x</value>
+ </list>
+</element>
+</correct>
+<valid>
+<foo>x</foo>
+</valid>
+<valid>
+<foo> x </foo>
+</valid>
+<invalid>
+<foo>x x</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <oneOrMore>
+ <value type="string">x</value>
+ </oneOrMore>
+ </list>
+</element>
+</correct>
+<valid>
+<foo>x</foo>
+</valid>
+<valid>
+<foo> x x x x </foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo>x y</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <group>
+ <value type="string">x</value>
+ <value type="string">y</value>
+ </group>
+ </list>
+</element>
+</correct>
+<valid>
+<foo>x y</foo>
+</valid>
+<valid>
+<foo>x y</foo>
+</valid>
+<valid>
+<foo>&#xD;x&#xA;y&#x9;</foo>
+</valid>
+<invalid>
+<foo>x</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <group>
+ <data type="token"/>
+ <data type="token"/>
+ </group>
+ </list>
+</element>
+</correct>
+<valid>
+<foo>x y</foo>
+</valid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo>x y z</foo>
+</invalid>
+</testCase>
+<testCase>
+<section>6.2.10</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <list>
+ <value>x y</value>
+ </list>
+</element>
+</correct>
+<invalid>
+<foo>x y</foo>
+</invalid>
+</testCase>
+</testSuite>
+</testSuite>
+</testSuite>
+<testSuite>
+<section>7</section>
+<testSuite>
+<section>7.1</section>
+<testCase>
+<section>7.1.1</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <attribute name="bar">
+ <element name="baz">
+ <empty/>
+ </element>
+ </attribute>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.1</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <attribute name="bar">
+ <choice>
+ <element name="baz">
+ <empty/>
+ </element>
+ <text/>
+ </choice>
+ </attribute>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.1</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <attribute name="bar">
+ <attribute name="baz"/>
+ </attribute>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.1</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <attribute name="bar">
+ <choice>
+ <attribute name="baz"/>
+ <text/>
+ </choice>
+ </attribute>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <group>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </group>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <group>
+ <attribute>
+ <anyName/>
+ </attribute>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </group>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <choice>
+ <group>
+ <choice>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </choice>
+ <choice>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </choice>
+ </group>
+ <attribute name="bar"/>
+ </choice>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <interleave>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </interleave>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <interleave>
+ <attribute>
+ <anyName/>
+ </attribute>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </interleave>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <choice>
+ <interleave>
+ <choice>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </choice>
+ <choice>
+ <attribute name="bar"/>
+ <attribute name="baz"/>
+ </choice>
+ </interleave>
+ <attribute name="bar"/>
+ </choice>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <list>
+ <data type="token"/>
+ </list>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <choice>
+ <list>
+ <data type="token"/>
+ </list>
+ <data type="token"/>
+ </choice>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <element name="bar">
+ <empty/>
+ </element>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <choice>
+ <data type="token"/>
+ <element name="bar">
+ <empty/>
+ </element>
+ </choice>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <attribute name="bar">
+ <empty/>
+ </attribute>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <choice>
+ <attribute name="bar">
+ <empty/>
+ </attribute>
+ <data type="token"/>
+ </choice>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <choice>
+ <text/>
+ <data type="token"/>
+ </choice>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <interleave>
+ <value>x</value>
+ <value>y</value>
+ </interleave>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.3</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <list>
+ <choice>
+ <interleave>
+ <value>x</value>
+ <value>y</value>
+ </interleave>
+ <value>z</value>
+ </choice>
+ </list>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <attribute name="bar"/>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <element name="bar">
+ <empty/>
+ </element>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <text/>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <list>
+ <data type="token"/>
+ </list>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <group>
+ <data type="token"/>
+ <data type="token"/>
+ </group>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <interleave>
+ <data type="token"/>
+ <data type="token"/>
+ </interleave>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <oneOrMore>
+ <data type="token"/>
+ </oneOrMore>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.4</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <data type="string">
+ <except>
+ <empty/>
+ </except>
+ </data>
+ </element>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <attribute name="foo"/>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <data type="string"/>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <data type="string"/>
+ <element name="foo">
+ <empty/>
+ </element>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <value>foo</value>
+ <element name="foo">
+ <empty/>
+ </element>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <text/>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <text/>
+ <element name="foo">
+ <empty/>
+ </element>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <list>
+ <data type="token"/>
+ </list>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <list>
+ <data type="token"/>
+ </list>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <group>
+ <element name="foo">
+ <empty/>
+ </element>
+ <element name="foo">
+ <empty/>
+ </element>
+ </group>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <element name="foo">
+ <empty/>
+ </element>
+ <element name="foo">
+ <empty/>
+ </element>
+ </group>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <interleave>
+ <element name="foo">
+ <empty/>
+ </element>
+ <element name="foo">
+ <empty/>
+ </element>
+ </interleave>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <interleave>
+ <element name="foo">
+ <empty/>
+ </element>
+ <element name="foo">
+ <empty/>
+ </element>
+ </interleave>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <oneOrMore>
+ <element name="foo">
+ <empty/>
+ </element>
+ </oneOrMore>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <oneOrMore>
+ <element name="foo">
+ <empty/>
+ </element>
+ </oneOrMore>
+ <element name="foo">
+ <empty/>
+ </element>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <empty/>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <choice>
+ <element name="foo">
+ <empty/>
+ </element>
+ <empty/>
+ </choice>
+</start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<section>7</section>
+<section>4.18</section>
+<documentation>Tests that constraints are post-normalization</documentation>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <grammar>
+ <start>
+ <text/>
+ </start>
+ </grammar>
+</element>
+</correct>
+<valid>
+<foo>text</foo>
+</valid>
+</testCase>
+<testCase>
+<section>7.1.5</section>
+<section>7</section>
+<section>4.18</section>
+<incorrect>
+<text xmlns="http://relaxng.org/ns/structure/1.0"/>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.1.1</section>
+<section>7</section>
+<section>4.20</section>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <optional>
+ <attribute name="bar">
+ <group>
+ <notAllowed/>
+ <attribute name="baz"/>
+ </group>
+ </attribute>
+ </optional>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>7.1.1</section>
+<section>7</section>
+<section>4.20</section>
+<documentation>The nested attribute element is normalized out because
+of the not allowed.</documentation>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <attribute name="bar">
+ <choice>
+ <text/>
+ <group>
+ <notAllowed/>
+ <attribute name="baz"/>
+ </group>
+ </choice>
+ </attribute>
+</element>
+</correct>
+<valid>
+<foo bar="baz"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<section>7</section>
+<section>4.12</section>
+<documentation>The group element is normalized out.</documentation>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <group>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </group>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</correct>
+<valid>
+<foo xyzzy1="val1" xyzzy2="val2"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<section>7</section>
+<section>4.21</section>
+<documentation>The group element is normalized out.</documentation>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <oneOrMore>
+ <group>
+ <attribute>
+ <anyName/>
+ </attribute>
+ <empty/>
+ </group>
+ </oneOrMore>
+ </element>
+</start>
+</grammar>
+</correct>
+<valid>
+<foo xyzzy1="val1" xyzzy2="val2"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.1.2</section>
+<section>7</section>
+<section>4.20</section>
+<documentation>The attribute elements are all normalized out.</documentation>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="foo">
+ <optional>
+ <attribute name="a1">
+ <attribute name="a2">
+ <attribute name="a3">
+ <notAllowed/>
+ </attribute>
+ </attribute>
+ </attribute>
+ </optional>
+</element>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+</testSuite>
+<testSuite>
+<section>7.2</section>
+<testCase>
+<section>7.2</section>
+<incorrect>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <element name="foo">
+ <group>
+ <data type="token"/>
+ <data type="token"/>
+ </group>
+ </element>
+ </start>
+</grammar>
+</incorrect>
+</testCase>
+<testCase>
+<documentation>Checks that normalization of notAllowed happens
+before string sequence checking.</documentation>
+<section>7.2</section>
+<section>4.20</section>
+<correct>
+<choice xmlns="http://relaxng.org/ns/structure/1.0">
+ <element name="foo">
+ <empty/>
+ </element>
+ <group>
+ <notAllowed/>
+ <element name="bar">
+ <group>
+ <data type="token"/>
+ <data type="token"/>
+ </group>
+ </element>
+ </group>
+</choice>
+</correct>
+<valid>
+<foo/>
+</valid>
+</testCase>
+<testCase>
+<section>4.20</section>
+<section>7.2</section>
+<documentation>notAllowed in an element is not normalized</documentation>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <group>
+ <element name="bar">
+ <notAllowed/>
+ </element>
+ <data type="token"/>
+ <data type="token"/>
+ </group>
+ <element name="baz">
+ <empty/>
+ </element>
+ </choice>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>7.3</section>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <attribute name="bar"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <zeroOrMore>
+ <attribute name="bar"/>
+ </zeroOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute name="bar"/>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo bar="xx"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <attribute name="bar"/>
+ <attribute name="bar"/>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <optional>
+ <attribute name="bar"/>
+ </optional>
+ <optional>
+ <attribute name="bar"/>
+ </optional>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <oneOrMore>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <name>baz</name>
+ </except>
+ </anyName>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <name>bar</name>
+ </except>
+ </anyName>
+ </attribute>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo bar="val" xyzzy="anotherval"/>
+</valid>
+<valid>
+<foo bar="val" baz=""/>
+</valid>
+<invalid>
+<foo bar="val"/>
+</invalid>
+<invalid>
+<foo/>
+</invalid>
+<invalid>
+<foo xyzzy="val"/>
+</invalid>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <oneOrMore>
+ <attribute>
+ <nsName ns=""/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <oneOrMore>
+ <attribute>
+ <nsName ns="">
+ <except>
+ <name>baz</name>
+ </except>
+ </nsName>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </oneOrMore>
+ <oneOrMore>
+ <attribute>
+ <nsName ns=""/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </oneOrMore>
+ <oneOrMore>
+ <attribute>
+ <anyName/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <nsName ns=""/>
+ </attribute>
+ </oneOrMore>
+ <oneOrMore>
+ <attribute>
+ <nsName ns="">
+ <except>
+ <name>bar</name>
+ </except>
+ </nsName>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <nsName>
+ <except>
+ <name>foo</name>
+ </except>
+ </nsName>
+ </except>
+ </anyName>
+ </attribute>
+ </oneOrMore>
+ <attribute name="foo"/>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <nsName>
+ <except>
+ <name>foo</name>
+ </except>
+ </nsName>
+ </except>
+ </anyName>
+ </attribute>
+ </oneOrMore>
+ <oneOrMore>
+ <attribute>
+ <nsName/>
+ </attribute>
+ </oneOrMore>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <anyName>
+ <except>
+ <nsName>
+ <except>
+ <name>bar</name>
+ </except>
+ </nsName>
+ </except>
+ </anyName>
+ </attribute>
+ </oneOrMore>
+ <attribute name="baz"/>
+</element>
+</correct>
+<valid>
+<foo bar="xx" baz="yy"/>
+</valid>
+<invalid>
+<foo x="xx" baz="yy"/>
+</invalid>
+<valid>
+<foo xmlns:eg="http://www.example.com/" eg:x="xx" baz="yy"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <oneOrMore>
+ <attribute>
+ <nsName ns="http://www.example.com/1"/>
+ </attribute>
+ </oneOrMore>
+ <oneOrMore>
+ <attribute>
+ <nsName ns="http://www.example.com/2"/>
+ </attribute>
+ </oneOrMore>
+</element>
+</correct>
+<valid>
+<foo xmlns:eg1="http://www.example.com/1"
+ xmlns:eg2="http://www.example.com/2"
+ eg1:x="xx" eg2:y="yy"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.3</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <choice>
+ <attribute name="bar"/>
+ <attribute name="bar"/>
+ </choice>
+</element>
+</correct>
+<valid>
+<foo bar="xx"/>
+</valid>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute name="bar"/>
+ <choice>
+ <attribute name="baz"/>
+ <attribute name="bar"/>
+ </choice>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute><anyName/><text/></attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute><nsName ns =""/><text/></attribute>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.3</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <attribute><choice><nsName ns =""/><name>foo</name></choice><text/></attribute>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+<testSuite>
+<section>7.4</section>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <interleave>
+ <element name="baz">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </interleave>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <group>
+ <element name="baz">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </group>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <group>
+ <element name="baz">
+ <empty/>
+ </element>
+ <interleave>
+ <element name="baz">
+ <empty/>
+ </element>
+ <element name="bar">
+ <empty/>
+ </element>
+ </interleave>
+ </group>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <optional>
+ <element name="bar">
+ <empty/>
+ </element>
+ </optional>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element>
+ <nsName ns=""/>
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element>
+ <anyName/>
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <notAllowed/>
+ </element>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element>
+ <anyName>
+ <except>
+ <name>bar</name>
+ </except>
+ </anyName>
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+</testCase>
+<testCase>
+<section>7.4</section>
+<correct>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <choice>
+ <element name="bar">
+ <empty/>
+ </element>
+ <element name="bar">
+ <text/>
+ </element>
+ </choice>
+ <element name="baz">
+ <empty/>
+ </element>
+ </interleave>
+</element>
+</correct>
+<valid>
+<foo><bar/><baz/></foo>
+</valid>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <interleave>
+ <text/>
+ <text/>
+ </interleave>
+</element>
+</incorrect>
+</testCase>
+<testCase>
+<section>7.4</section>
+<incorrect>
+<element name="foo" xmlns="http://relaxng.org/ns/structure/1.0">
+ <mixed>
+ <mixed>
+ <element name="bar">
+ <empty/>
+ </element>
+ </mixed>
+ <element name="baz">
+ <empty/>
+ </element>
+ </mixed>
+</element>
+</incorrect>
+</testCase>
+</testSuite>
+</testSuite>
+<testSuite>
+<documentation>Regressions</documentation>
+<testCase>
+<correct>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+<start>
+ <element name="foo">
+ <choice>
+ <group>
+ <attribute name="bar"><empty/></attribute>
+ <element name="baz1"><empty/></element>
+ </group>
+ <group>
+ <attribute name="bar"><text/></attribute>
+ <element name="baz2"><empty/></element>
+ </group>
+ </choice>
+ </element>
+</start>
+</grammar>
+</correct>
+<valid>
+<foo bar=" "><baz1/></foo>
+</valid>
+</testCase>
+<testCase>
+<correct>
+<notAllowed xmlns="http://relaxng.org/ns/structure/1.0"/>
+</correct>
+<invalid>
+<foo/>
+</invalid>
+</testCase>
+</testSuite>
+</testSuite>
diff --git a/split.xsl b/split.xsl
new file mode 100644
index 0000000..6847f1f
--- /dev/null
+++ b/split.xsl
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:saxon="http://icl.com/saxon"
+ extension-element-prefixes="saxon">
+
+<xsl:output method="text"/>
+
+<xsl:param name="dir" select="'.'"/>
+
+<xsl:template match="/">
+ <xsl:apply-templates select="//testCase"/>
+</xsl:template>
+
+<xsl:variable name="incorrectSchemaName" select="'i.rng'"/>
+<xsl:variable name="correctSchemaName" select="'c.rng'"/>
+<xsl:variable name="invalidInstanceSuffix" select="'.i.xml'"/>
+<xsl:variable name="validInstanceSuffix" select="'.v.xml'"/>
+
+<xsl:template match="testCase">
+ <xsl:variable name="b" select="concat($dir, '/', format-number(position(),'000'))"/>
+ <xsl:call-template name="mkdir">
+ <xsl:with-param name="dir" select="$b"/>
+ </xsl:call-template>
+ <xsl:variable name="f">
+ <xsl:choose>
+ <xsl:when test="correct">
+ <xsl:value-of select="$correctSchemaName"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$incorrectSchemaName"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <saxon:output href="{concat($b, '/', $f)}" method="xml">
+ <xsl:for-each select="correct|incorrect">
+ <xsl:call-template name="copy"/>
+ </xsl:for-each>
+ </saxon:output>
+ <xsl:apply-templates select="resource|dir">
+ <xsl:with-param name="base" select="$b"/>
+ </xsl:apply-templates>
+ <!-- Don't combine so that position is correct. -->
+ <xsl:apply-templates select="valid|invalid">
+ <xsl:with-param name="base" select="$b"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template match="valid">
+ <xsl:param name="base"/>
+ <xsl:variable name="d" select="concat($base, '/', position(), $validInstanceSuffix)"/>
+ <saxon:output href="{$d}" method="xml">
+ <xsl:call-template name="copy"/>
+ </saxon:output>
+</xsl:template>
+
+<xsl:template match="invalid">
+ <xsl:param name="base"/>
+ <xsl:variable name="d" select="concat($base, '/', position(), $invalidInstanceSuffix)"/>
+ <saxon:output href="{$d}" method="xml">
+ <xsl:call-template name="copy"/>
+ </saxon:output>
+</xsl:template>
+
+<xsl:template match="resource">
+ <xsl:param name="base"/>
+ <saxon:output href="{$base}/{@name}" method="xml">
+ <xsl:call-template name="copy"/>
+ </saxon:output>
+</xsl:template>
+
+<xsl:template name="copy">
+ <xsl:if test="@dtd">
+ <xsl:value-of select="@dtd" disable-output-escaping="yes"/>
+ </xsl:if>
+ <xsl:copy-of select="node()"/>
+</xsl:template>
+
+<xsl:template match="dir">
+ <xsl:param name="base"/>
+ <xsl:variable name="d" select="concat($base, '/', @name)"/>
+ <xsl:call-template name="mkdir">
+ <xsl:with-param name="dir" select="$d"/>
+ </xsl:call-template>
+ <xsl:apply-templates select="resource|dir">
+ <xsl:with-param name="base" select="$d"/>
+ </xsl:apply-templates>
+</xsl:template>
+
+<xsl:template name="mkdir">
+ <xsl:param name="dir"/>
+ <xsl:value-of select="substring(File:mkdir(File:new($dir)),0,0)"
+ xmlns:File="java:java.io.File"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/testSuite.rng b/testSuite.rng
new file mode 100644
index 0000000..e3649c6
--- /dev/null
+++ b/testSuite.rng
@@ -0,0 +1,157 @@
+<?xml version="1.0"?>
+<!-- $Id: testSuite.rng,v 1.10 2002/04/30 07:00:05 jjc Exp $ -->
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" ns="">
+ <!--
+ Target namespace is intentionally set to "" so as not to interfere with
+ prefix/URI bindings
+ -->
+
+ <start>
+ <ref name="testSuite"/>
+ </start>
+
+ <define name="testSuite">
+ <element name="testSuite">
+ <ref name="header"/>
+ <zeroOrMore>
+ <choice>
+ <ref name="testSuite"/>
+ <ref name="testCase"/>
+ </choice>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="testCase">
+ <element name="testCase">
+ <ref name="header"/>
+
+ <ref name="resources"/>
+
+ <choice>
+
+ <!-- Incorrect schema -->
+ <element name="incorrect">
+ <ref name="dtd"/>
+ <ref name="anyElement"/>
+ </element>
+
+ <!-- Correct schema and test cases -->
+ <group>
+ <element name="correct">
+ <ref name="dtd"/>
+ <externalRef href="relaxng.rng"/>
+ </element>
+ <zeroOrMore>
+ <choice>
+ <!-- Valid test cases -->
+ <element name="valid">
+ <ref name="dtd"/>
+ <ref name="anyElement"/>
+ </element>
+ <!-- Invalid test cases -->
+ <element name="invalid">
+ <ref name="dtd"/>
+ <ref name="anyElement"/>
+ </element>
+ </choice>
+ </zeroOrMore>
+ </group>
+
+ </choice>
+
+ </element>
+ </define>
+
+ <define name="any">
+ <zeroOrMore>
+ <choice>
+ <ref name="anyElement"/>
+ <attribute>
+ <anyName/>
+ <text/>
+ </attribute>
+ <text/>
+ </choice>
+ </zeroOrMore>
+ </define>
+
+ <define name="anyElement">
+ <element>
+ <anyName/>
+ <ref name="any"/>
+ </element>
+ </define>
+
+ <define name="header">
+ <zeroOrMore>
+ <choice>
+ <element name="title">
+ <text/>
+ </element>
+ <element name="documentation">
+ <text/>
+ </element>
+ <element name="author">
+ <text/>
+ </element>
+ <!-- Email address for correspondence about test cases. -->
+ <element name="email">
+ <text/>
+ </element>
+ <!-- Section of the specification being tested. -->
+ <element name="section">
+ <text/>
+ </element>
+ <element name="requires">
+ <attribute name="datatypeLibrary"/>
+ </element>
+ <element>
+ <anyName>
+ <except>
+ <nsName/>
+ </except>
+ </anyName>
+ <ref name="any"/>
+ </element>
+ </choice>
+ </zeroOrMore>
+ </define>
+
+ <define name="resources">
+ <zeroOrMore>
+ <choice>
+ <element name="resource">
+ <attribute name="name">
+ <ref name="pathSegment"/>
+ </attribute>
+ <ref name="dtd"/>
+ <ref name="anyElement"/>
+ </element>
+ <element name="dir">
+ <attribute name="name">
+ <ref name="pathSegment"/>
+ </attribute>
+ <ref name="resources"/>
+ </element>
+ </choice>
+ </zeroOrMore>
+ </define>
+
+ <define name="dtd">
+ <optional>
+ <attribute name="dtd"/>
+ </optional>
+ </define>
+
+ <!-- A relative URI segment. -->
+
+ <define name="pathSegment">
+ <data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
+ type="string">
+ <!-- one or more RFC 2396 pchars -->
+ <param name="pattern">([\-A-Za-z0-9:@&amp;=+$,_.!~*'()]|%[0-9a-fA-F][0-9a-fA-F])+</param>
+ </data>
+ </define>
+
+</grammar>
diff --git a/xmlcat b/xmlcat
new file mode 100755
index 0000000..67adf1a
--- /dev/null
+++ b/xmlcat
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+import sys
+from xml.sax import handler, make_parser
+from xml.sax.saxutils import escape
+
+class ContentGenerator(handler.ContentHandler):
+ def __init__(self, out=sys.stdout):
+ handler.ContentHandler.__init__(self)
+ self._out = out
+ def startDocument(self):
+ xml_decl = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
+ self._out.write(xml_decl)
+ def endDocument(self):
+ self._out.write('\n')
+ def startElement(self, name, attrs):
+ self._out.write('<' + name)
+ name_val = attrs.items()
+ name_val.sort() # canonicalize attributes
+ for (name, value) in name_val:
+ self._out.write(' %s="%s"' % (name, escape(value)))
+ self._out.write('>')
+ def endElement(self, name):
+ self._out.write('</%s>' % name)
+ def characters(self, content):
+ self._out.write(escape(content))
+ def ignorableWhitespace(self, content):
+ self._out.write(content)
+ def processingInstruction(self, target, data):
+ self._out.write('<?%s %s?>' % (target, data))
+
+if __name__=='__main__':
+ parser = make_parser()
+ parser.setContentHandler(ContentGenerator())
+ parser.parse(sys.argv[1])
diff --git a/xsdtest.rnc b/xsdtest.rnc
new file mode 100644
index 0000000..d0e7aab
--- /dev/null
+++ b/xsdtest.rnc
@@ -0,0 +1,22 @@
+datatypes xsd = "http://www.w3.org/2001/XMLSchema-datatypes"
+
+start =
+ element xsdtest {
+ element datatype {
+ attribute name { xsd:NCName },
+ ((param*, (valid|invalid)*)
+ | (valid|invalid|equiv|length|lessThan|incomparable)*)
+ }*
+ }
+
+param = element param { attribute name { xsd:NCName }, string }
+valid = element valid { internalSubset?, string }
+invalid = element invalid { internalSubset?, string }
+equiv = element equiv { element class { value+ }+ }
+
+value = element value { internalSubset?, string }
+length = element length { attribute value { xsd:integer }, internalSubset?, string }
+lessThan = element lessThan { value, value }
+incomparable = element incomparable { value, value }
+
+internalSubset = attribute internalSubset { string }
diff --git a/xsdtest.rng b/xsdtest.rng
new file mode 100644
index 0000000..bd760d1
--- /dev/null
+++ b/xsdtest.rng
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <start>
+ <element name="xsdtest">
+ <zeroOrMore>
+ <element name="datatype">
+ <attribute name="name">
+ <data type="NCName"/>
+ </attribute>
+ <choice>
+ <group>
+ <zeroOrMore>
+ <ref name="param"/>
+ </zeroOrMore>
+ <zeroOrMore>
+ <choice>
+ <ref name="valid"/>
+ <ref name="invalid"/>
+ </choice>
+ </zeroOrMore>
+ </group>
+ <zeroOrMore>
+ <choice>
+ <ref name="valid"/>
+ <ref name="invalid"/>
+ <ref name="equiv"/>
+ <ref name="length"/>
+ <ref name="lessThan"/>
+ <ref name="incomparable"/>
+ </choice>
+ </zeroOrMore>
+ </choice>
+ </element>
+ </zeroOrMore>
+ </element>
+ </start>
+ <define name="param">
+ <element name="param">
+ <attribute name="name">
+ <data type="NCName"/>
+ </attribute>
+ <data type="string" datatypeLibrary=""/>
+ </element>
+ </define>
+ <define name="valid">
+ <element name="valid">
+ <optional>
+ <ref name="internalSubset"/>
+ </optional>
+ <data type="string" datatypeLibrary=""/>
+ </element>
+ </define>
+ <define name="invalid">
+ <element name="invalid">
+ <optional>
+ <ref name="internalSubset"/>
+ </optional>
+ <data type="string" datatypeLibrary=""/>
+ </element>
+ </define>
+ <define name="equiv">
+ <element name="equiv">
+ <oneOrMore>
+ <element name="class">
+ <oneOrMore>
+ <ref name="value"/>
+ </oneOrMore>
+ </element>
+ </oneOrMore>
+ </element>
+ </define>
+ <define name="value">
+ <element name="value">
+ <optional>
+ <ref name="internalSubset"/>
+ </optional>
+ <data type="string" datatypeLibrary=""/>
+ </element>
+ </define>
+ <define name="length">
+ <element name="length">
+ <attribute name="value">
+ <data type="integer"/>
+ </attribute>
+ <optional>
+ <ref name="internalSubset"/>
+ </optional>
+ <data type="string" datatypeLibrary=""/>
+ </element>
+ </define>
+ <define name="lessThan">
+ <element name="lessThan">
+ <ref name="value"/>
+ <ref name="value"/>
+ </element>
+ </define>
+ <define name="incomparable">
+ <element name="incomparable">
+ <ref name="value"/>
+ <ref name="value"/>
+ </element>
+ </define>
+ <define name="internalSubset">
+ <attribute name="internalSubset">
+ <data type="string" datatypeLibrary=""/>
+ </attribute>
+ </define>
+</grammar>
diff --git a/xsdtest.xml b/xsdtest.xml
new file mode 100644
index 0000000..a30b01c
--- /dev/null
+++ b/xsdtest.xml
@@ -0,0 +1,805 @@
+<xsdtest>
+<datatype name="dateTime">
+<valid>2001-12-01T19:45:00</valid>
+<valid>2001-12-01T19:45:00Z</valid>
+<valid>2001-12-01T19:45:00-11:59</valid>
+<valid>0001-01-12T00:00:00+12:00</valid>
+<invalid>2001-12-1T19:45:00+24:00</invalid>
+<invalid>2001-12-1T19:45:00</invalid>
+<equiv>
+<class>
+ <value>2001-12-01T19:45:00</value>
+ <value>2001-12-01T19:45:00.00</value>
+</class>
+<class>
+ <value>2001-12-01T19:45:00Z</value>
+ <value>2001-12-01T19:45:00.00Z</value>
+ <value>2001-12-01T20:45:00+01:00</value>
+</class>
+</equiv>
+</datatype>
+<datatype name="anyURI">
+<valid>foobar</valid>
+<valid>http://www.example.com</valid>
+<valid>http://www.example.co%6d</valid>
+<valid>nosuchscheme:stuff</valid>
+<invalid>foo$bar:stuff</invalid>
+<invalid>f%oobar</invalid>
+</datatype>
+<datatype name="integer">
+<valid>10</valid>
+<valid>01</valid>
+<valid>0123456789</valid>
+<valid>+10</valid>
+<valid>-10</valid>
+<invalid>1.0</invalid>
+<invalid>.1</invalid>
+<valid>9999999999999999999999999999999</valid>
+<invalid>1.</invalid>
+<invalid>0.</invalid>
+<equiv>
+<class>
+ <value>0</value>
+ <value>+0</value>
+ <value>-0</value>
+ <value>00</value>
+</class>
+<class>
+ <value>10</value>
+ <value>+10</value>
+ <value>+0010</value>
+ <value>010</value>
+</class>
+<class>
+ <value>-10</value>
+ <value>-0010</value>
+ <value>-010</value>
+</class>
+</equiv>
+</datatype>
+<datatype name="duration">
+<valid>P1Y</valid>
+<valid>P1Y0M2DT17H5M12S</valid>
+<valid>-P1Y</valid>
+<valid>P60D</valid>
+<valid>PT24H</valid>
+<valid>PT1.2S</valid>
+<invalid>P24h</invalid>
+<invalid>P24H</invalid>
+<invalid>P1YT</invalid>
+<invalid>P</invalid>
+<invalid>-P</invalid>
+<equiv>
+ <class>
+ <value>-P6M</value>
+ </class>
+ <class>
+ <value>P0Y</value>
+ <value>-P0Y</value>
+ </class>
+ <class>
+ <value>P1Y</value>
+ <value>P001Y</value>
+ <value>P001Y0M</value>
+ <value>P1Y0M0DT0H0M0.0S</value>
+ </class>
+ <class>
+ <value>P6M</value>
+ </class>
+ <class>
+ <value>PT6M</value>
+ </class>
+ <class>
+ <value>PT1S</value>
+ <value>PT1.0S</value>
+ </class>
+</equiv>
+<lessThan>
+ <value>PT1M</value>
+ <value>PT61S</value>
+</lessThan>
+<lessThan>
+ <value>PT59S</value>
+ <value>PT1M</value>
+</lessThan>
+<incomparable>
+ <value>PT60S</value>
+ <value>PT1M</value>
+</incomparable>
+<lessThan>
+ <value>PT1H</value>
+ <value>PT61M</value>
+</lessThan>
+<lessThan>
+ <value>PT59M</value>
+ <value>PT1H</value>
+</lessThan>
+<incomparable>
+ <value>PT60M</value>
+ <value>PT1H</value>
+</incomparable>
+<lessThan>
+ <value>P1D</value>
+ <value>PT25H</value>
+</lessThan>
+<lessThan>
+ <value>PT23H</value>
+ <value>P1D</value>
+</lessThan>
+<incomparable>
+ <value>P1D</value>
+ <value>PT24H</value>
+</incomparable>
+<lessThan>
+ <value>P1Y</value>
+ <value>P13M</value>
+</lessThan>
+<lessThan>
+ <value>P11M</value>
+ <value>P1Y</value>
+</lessThan>
+<incomparable>
+ <value>P12M</value>
+ <value>P1Y</value>
+</incomparable>
+<lessThan>
+ <value>P364D</value>
+ <value>P1Y</value>
+</lessThan>
+<incomparable>
+ <value>P1Y</value>
+ <value>P365D</value>
+</incomparable>
+<incomparable>
+ <value>P1Y</value>
+ <value>P366D</value>
+</incomparable>
+<lessThan>
+ <value>P1Y</value>
+ <value>P367D</value>
+</lessThan>
+<lessThan>
+ <value>P149D</value>
+ <value>P5M</value>
+</lessThan>
+<incomparable>
+ <value>P150D</value>
+ <value>P5M</value>
+</incomparable>
+<incomparable>
+ <value>P151D</value>
+ <value>P5M</value>
+</incomparable>
+<incomparable>
+ <value>P152D</value>
+ <value>P5M</value>
+</incomparable>
+<incomparable>
+ <value>P153D</value>
+ <value>P5M</value>
+</incomparable>
+<lessThan>
+ <value>P5M</value>
+ <value>P154D</value>
+</lessThan>
+<lessThan>
+ <value>P27D</value>
+ <value>P1M</value>
+</lessThan>
+<incomparable>
+ <value>P28D</value>
+ <value>P1M</value>
+</incomparable>
+<incomparable>
+ <value>P29D</value>
+ <value>P1M</value>
+</incomparable>
+<incomparable>
+ <value>P30D</value>
+ <value>P1M</value>
+</incomparable>
+<incomparable>
+ <value>P31D</value>
+ <value>P1M</value>
+</incomparable>
+<lessThan>
+ <value>P1M</value>
+ <value>P32D</value>
+</lessThan>
+</datatype>
+<datatype name="time">
+<valid>12:45:00</valid>
+<valid>12:45:00Z</valid>
+</datatype>
+<datatype name="date">
+<valid>1886-12-01</valid>
+<valid>1886-12-01Z</valid>
+<lessThan>
+ <value>1066-12-31</value>
+ <value>1900-01-01</value>
+</lessThan>
+<lessThan>
+ <value>1900-01-01</value>
+ <value>1900-01-02</value>
+</lessThan>
+</datatype>
+<datatype name="gYearMonth">
+<valid>1996-12</valid>
+<valid>1996-01</valid>
+<valid>1996-01Z</valid>
+<invalid>1996-00</invalid>
+<equiv>
+<class><value>1996-01</value></class>
+<class>
+ <value>1996-01Z</value>
+ <value>1996-01+00:00</value>
+ <value>1996-01-00:00</value>
+</class>
+<class><value>1996-01+01:00</value></class>
+<class><value>1996-01-01:00</value></class>
+</equiv>
+</datatype>
+<datatype name="gYear">
+<valid>2001</valid>
+<valid>2001Z</valid>
+<lessThan>
+ <value>1999</value>
+ <value>2000</value>
+</lessThan>
+<lessThan>
+ <value>1999+07:00</value>
+ <value>2000+07:00</value>
+</lessThan>
+</datatype>
+<datatype name="gMonthDay">
+<valid>--12-01</valid>
+<valid>--12-01Z</valid>
+<lessThan>
+ <value>--12-01</value>
+ <value>--12-04</value>
+</lessThan>
+<lessThan>
+ <value>--11-17</value>
+ <value>--12-04</value>
+</lessThan>
+</datatype>
+<datatype name="gDay">
+<valid>---20</valid>
+<valid>---20Z</valid>
+<lessThan>
+ <value>---01</value>
+ <value>---31</value>
+</lessThan>
+</datatype>
+<datatype name="gMonth">
+<valid>--12</valid>
+<valid>--01</valid>
+<valid>--01Z</valid>
+<valid> --12 </valid>
+<invalid>---01</invalid>
+<invalid>--00</invalid>
+<invalid>--13</invalid>
+<invalid>- -13</invalid>
+<lessThan>
+ <value>--01</value>
+ <value>--12</value>
+</lessThan>
+<lessThan>
+ <value>--01</value>
+ <value>--02</value>
+</lessThan>
+</datatype>
+<datatype name="boolean">
+<valid>true</valid>
+<valid>false</valid>
+<valid>0</valid>
+<valid>1</valid>
+<invalid>00</invalid>
+<invalid>00</invalid>
+<invalid>01</invalid>
+<equiv>
+<class><value>true</value><value>1</value></class>
+<class><value>false</value><value>0</value></class>
+</equiv>
+</datatype>
+<datatype name="base64Binary">
+<valid>AAAA</valid>
+<valid>abcd efgh ijkl mnop qrst uvwx yzAB CDEF GHIJ KLMN OPQR
+STUV WXYZ 0123 4567 89+/</valid>
+<valid>BA==</valid>
+<valid></valid>
+<valid>BA==</valid>
+<valid>BQ==</valid>
+<valid>Bg==</valid>
+<valid>Bw==</valid>
+<valid>BBA=</valid>
+<valid>BBA=</valid>
+<valid>BBE=</valid>
+<valid>BBI=</valid>
+<valid>BBM=</valid>
+<valid>BBQ=</valid>
+<valid>BBU=</valid>
+<valid>BBY=</valid>
+<valid>BBc=</valid>
+<valid>BBg=</valid>
+<valid>BBk=</valid>
+<valid>BBo=</valid>
+<valid>BBs=</valid>
+<valid>BBw=</valid>
+<valid>BB0=</valid>
+<valid>BB4=</valid>
+<valid>BB8=</valid>
+<invalid>====</invalid>
+<invalid>BB==</invalid>
+<invalid>BBB=</invalid>
+<invalid>B===</invalid>
+<invalid>B</invalid>
+<equiv>
+<class>
+<value>deadbeef</value>
+<value>d&#xA;&#xD;&#x9;e a d
+b eef </value>
+</class>
+<class>
+<value>DEADBEEF</value>
+<value>D&#xA;&#xD;&#x9;E A D
+B EEF </value>
+</class>
+</equiv>
+<length value="0"></length>
+<length value="6">deadbeef</length>
+<length value="1">BA==</length>
+<length value="2">BBA=</length>
+<length value="3">dead</length>
+<length value="4">deadBA==</length>
+</datatype>
+<datatype name="hexBinary">
+<valid>deadbeef</valid>
+<valid></valid>
+<valid>0123456789ABCDEFabcdef</valid>
+<invalid>00 00</invalid>
+<invalid>00.00</invalid>
+<invalid>0G</invalid>
+<equiv>
+ <class>
+ <value>00</value>
+ <value>
+ 00
+ </value>
+ </class>
+ <class>
+ <value>01</value>
+ </class>
+ <class>
+ <value>10</value>
+ </class>
+ <class>
+ <value>0a</value>
+ <value>0A</value>
+ </class>
+</equiv>
+<length value="0"></length>
+<length value="1">00</length>
+<length value="2">0000</length>
+<length value="2"> 0000 </length>
+<length value="2">AAAA</length>
+</datatype>
+<datatype name="float">
+<valid>1.0</valid>
+<valid>1.</valid>
+<valid>.1</valid>
+<invalid>- 1</invalid>
+<invalid>1 .0</invalid>
+<invalid>+INF</invalid>
+<invalid>+NaN</invalid>
+<invalid>-NaN</invalid>
+<equiv>
+<class>
+ <value>0</value>
+ <value>-0</value>
+ <value>+0</value>
+ <value> 0 </value>
+ <value> 0. </value>
+ <value> .0 </value>
+ <value> 0.0 </value>
+ <value> 0e0 </value>
+ <value> 0E0 </value>
+ <value> 0E+0 </value>
+ <value> 0E-0 </value>
+</class>
+<class>
+ <value>1E0</value>
+ <value>0.1E1</value>
+ <value>10E-1</value>
+ <value>+1</value>
+</class>
+<class>
+ <value>-1</value>
+</class>
+<class>
+ <value>INF</value>
+ <value>INF </value>
+</class>
+<class>
+ <value>-INF</value>
+ <value>-INF </value>
+</class>
+<class>
+ <value>NaN</value>
+ <value> NaN </value>
+</class>
+</equiv>
+<lessThan>
+ <value>-INF</value>
+ <value>-1000</value>
+</lessThan>
+<lessThan>
+ <value>1000</value>
+ <value>INF</value>
+</lessThan>
+<lessThan>
+ <value>-1</value>
+ <value>1</value>
+</lessThan>
+<lessThan>
+ <value>0</value>
+ <value>1</value>
+</lessThan>
+<lessThan>
+ <value>-1</value>
+ <value>0</value>
+</lessThan>
+</datatype>
+<datatype name="double">
+<valid>1.0</valid>
+<valid>1.</valid>
+<valid>.1</valid>
+<invalid>- 1</invalid>
+<invalid>1 .0</invalid>
+<invalid>+INF</invalid>
+<invalid>+NaN</invalid>
+<invalid>-NaN</invalid>
+<equiv>
+<class>
+ <value>0</value>
+ <value>-0</value>
+ <value>+0</value>
+ <value> 0 </value>
+ <value> 0. </value>
+ <value> .0 </value>
+ <value> 0.0 </value>
+ <value> 0e0 </value>
+ <value> 0E0 </value>
+ <value> 0E+0 </value>
+ <value> 0E-0 </value>
+</class>
+<class>
+ <value>1E0</value>
+ <value>0.1E1</value>
+ <value>10E-1</value>
+ <value>+1</value>
+</class>
+<class>
+ <value>-1</value>
+</class>
+<class>
+ <value>INF</value>
+ <value>INF </value>
+</class>
+<class>
+ <value>-INF</value>
+ <value>-INF </value>
+</class>
+<class>
+ <value>NaN</value>
+ <value> NaN </value>
+</class>
+</equiv>
+<lessThan>
+ <value>-INF</value>
+ <value>-1000</value>
+</lessThan>
+<lessThan>
+ <value>1000</value>
+ <value>INF</value>
+</lessThan>
+<lessThan>
+ <value>-1</value>
+ <value>1</value>
+</lessThan>
+<lessThan>
+ <value>0</value>
+ <value>1</value>
+</lessThan>
+<lessThan>
+ <value>-1</value>
+ <value>0</value>
+</lessThan>
+</datatype>
+<datatype name="QName">
+<valid>foo</valid>
+<valid xmlns:x="http://www.example.com">x:foo</valid>
+<invalid>y:foo</invalid>
+<equiv xmlns:x="http://www.example.com"
+ xmlns:y="http://www.example.com/"
+ xmlns:z="http://www.example.com">
+<class>
+ <value>foo</value>
+ <value> foo</value>
+</class>
+<class>
+ <value>x:foo</value>
+ <value> x:foo </value>
+ <value>z:foo</value>
+</class>
+<class>
+ <value>x:bar</value>
+ <value>z:bar</value>
+</class>
+<class>
+ <value>y:foo</value>
+</class>
+<class>
+ <value>y:bar</value>
+</class>
+</equiv>
+</datatype>
+<datatype name="NOTATION">
+<valid>foo</valid>
+<valid xmlns:x="http://www.example.com">x:foo</valid>
+<invalid>y:foo</invalid>
+</datatype>
+<datatype name="decimal">
+<valid>1.0</valid>
+<valid>1.</valid>
+<valid>.1</valid>
+<valid>+1.0</valid>
+<valid>-1.0</valid>
+<valid> 1 </valid>
+<valid>99999999999999999999999999999999999999999999999999999999999999999</valid>
+<valid>-99999999999999999999999999999999999999999999999999999999999999999</valid>
+<invalid>junk</invalid>
+<invalid>--1</invalid>
+<invalid>++1</invalid>
+<invalid>+-1</invalid>
+<invalid>1.2.</invalid>
+<invalid>..1</invalid>
+<invalid>1..</invalid>
+<invalid>1 .2</invalid>
+<invalid>1+</invalid>
+<invalid>+ 1</invalid>
+<lessThan>
+ <value>0</value>
+ <value>1</value>
+</lessThan>
+</datatype>
+<datatype name="nonPositiveInteger">
+<valid>-1</valid>
+<valid>0</valid>
+<valid>-0</valid>
+<invalid>1</invalid>
+</datatype>
+<datatype name="nonNegativeInteger">
+<valid>1</valid>
+<valid>0</valid>
+<valid>+1</valid>
+<valid>+0</valid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="positiveInteger">
+<valid>+1</valid>
+<valid>1</valid>
+<invalid>0</invalid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="negativeInteger">
+<valid>-1</valid>
+<invalid>+1</invalid>
+<invalid>0</invalid>
+</datatype>
+<datatype name="long">
+<valid>1</valid>
+<valid>+1</valid>
+<valid>0</valid>
+<valid> 0 </valid>
+<invalid>1 2</invalid>
+<invalid>9999999999999999999999999999999999999999999999999999999999999999999999999</invalid>
+<valid>9223372036854775807</valid>
+<valid>-9223372036854775808</valid>
+<invalid>9223372036854775808</invalid>
+<invalid>-9223372036854775809</invalid>
+<invalid/>
+</datatype>
+<datatype name="int">
+<valid>1</valid>
+<valid>01</valid>
+<valid> 1 </valid>
+<valid>2147483647</valid>
+<valid>-2147483648</valid>
+<invalid>2147483648</invalid>
+<invalid>-2147483649</invalid>
+<invalid>9999999999999999999999999999999999999999999999999999999999999999999999999</invalid>
+<equiv>
+<class>
+ <value>1</value>
+ <value>+1</value>
+ <value> 1 </value>
+ <value>001</value>
+</class>
+<class>
+ <value>-1</value>
+ <value> -1 </value>
+ <value>-001</value>
+</class>
+</equiv>
+</datatype>
+<datatype name="short">
+<valid>1</valid>
+<valid>32767</valid>
+<valid>-32768</valid>
+<invalid>32768</invalid>
+<invalid>-32769</invalid>
+<invalid>9999999999999999999999999999999999999999999999999999999999999999999999999</invalid>
+<equiv>
+<class>
+ <value>1</value>
+ <value>+1</value>
+ <value> 1 </value>
+ <value>001</value>
+</class>
+<class>
+ <value>-1</value>
+ <value> -1 </value>
+ <value>-001</value>
+</class>
+</equiv>
+</datatype>
+<datatype name="byte">
+<valid>1</valid>
+<valid>127</valid>
+<valid>-128</valid>
+<invalid>128</invalid>
+<invalid>-129</invalid>
+</datatype>
+<datatype name="unsignedLong">
+<valid>1</valid>
+<valid>+1</valid>
+<invalid>-1</invalid>
+<valid>0</valid>
+<valid>18446744073709551615</valid>
+<invalid>18446744073709551616</invalid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="unsignedInt">
+<valid>1</valid>
+<valid>+1</valid>
+<valid>0</valid>
+<valid>4294967295</valid>
+<invalid>4294967296</invalid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="unsignedShort">
+<valid>1</valid>
+<valid>+1</valid>
+<valid>0</valid>
+<valid>65535</valid>
+<invalid>65536</invalid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="unsignedByte">
+<valid>1</valid>
+<valid>+1</valid>
+<valid>0</valid>
+<valid>255</valid>
+<invalid>256</invalid>
+<invalid>-1</invalid>
+</datatype>
+<datatype name="string">
+<valid>any thing at all!</valid>
+</datatype>
+<datatype name="normalizedString">
+<valid>any thing at all!</valid>
+</datatype>
+<datatype name="token">
+<valid>any thing at all!</valid>
+<equiv>
+<class>
+ <value/>
+ <value> </value>
+ <value>&#x9;&#xA;&#xD;&#x20;</value>
+</class>
+<class>
+ <value>x&#x20;</value>
+ <value>x&#xA;</value>
+ <value>x&#xD;</value>
+ <value>x&#x9;</value>
+ <value>&#x20;x</value>
+ <value>&#xA;x</value>
+ <value>&#xD;x</value>
+ <value>&#x9;x</value>
+ <value>&#x9;&#xA;&#xD;&#x20;x&#x9;&#xA;&#xD;&#x20;</value>
+</class>
+<class>
+ <value>x y&#x20;</value>
+ <value>x y&#xA;</value>
+ <value>x y&#xD;</value>
+ <value>x y&#x9;</value>
+ <value>x&#x20;y</value>
+ <value>x&#xA;y</value>
+ <value>x&#xD;y</value>
+ <value>x&#x9;y</value>
+ <value>&#x20;x y</value>
+ <value>&#xA;x y</value>
+ <value>&#xD;x y</value>
+ <value>&#x9;x y</value>
+ <value>&#x9;&#xA;&#xD;&#x20;x&#x9;&#xA;&#xD;&#x20;y&#x9;&#xA;&#xD;&#x20;</value>
+</class>
+</equiv>
+<length value="0"></length>
+<length value="1">x</length>
+<length value="1"> x </length>
+<length value="1">&#x10800;</length>
+</datatype>
+<datatype name="language">
+<valid>en</valid>
+<valid>en-UK</valid>
+<valid>i-cherokee</valid>
+<valid>x-klingon</valid>
+<valid>en-uk-scotland</valid>
+<invalid>en.UK</invalid>
+</datatype>
+<datatype name="Name">
+<valid>foo</valid>
+<valid>_0123456789</valid>
+<invalid>.</invalid>
+<valid>:</valid>
+<invalid>-</invalid>
+<invalid>1234</invalid>
+<valid> foo </valid>
+</datatype>
+<datatype name="NCName">
+<valid>foo</valid>
+<invalid>foo:bar</invalid>
+<invalid>0foo</invalid>
+<equiv>
+<class><value>foo</value><value> foo </value></class>
+<class><value>FOO</value><value> FOO </value></class>
+</equiv>
+</datatype>
+<datatype name="NMTOKEN">
+<valid>foo</valid>
+<valid>_</valid>
+<valid>.</valid>
+<valid>:</valid>
+<valid>-</valid>
+<valid>1234</valid>
+<valid> foo </valid>
+<length value="3"> foo </length>
+<length value="2">fo</length>
+<length value="1">f</length>
+</datatype>
+<datatype name="NMTOKENS">
+<valid>foo bar</valid>
+<invalid/>
+<valid>1 2 3 4</valid>
+</datatype>
+<datatype name="ID">
+<valid>foobar</valid>
+<invalid>foo:bar</invalid>
+<invalid>foo bar</invalid>
+</datatype>
+<datatype name="ENTITY">
+<invalid/>
+<invalid>foo</invalid>
+<valid internalSubset="&lt;!ENTITY foo SYSTEM 'whatever' NDATA jpeg>"
+>foo</valid>
+</datatype>
+<datatype name="ENTITIES">
+<invalid></invalid>
+<invalid>foo</invalid>
+<valid internalSubset="&lt;!ENTITY foo SYSTEM 'whatever' NDATA jpeg>
+&#xA;&lt;!ENTITY bar SYSTEM 'whatever' NDATA jpeg>
+"
+> foo bar </valid>
+</datatype>
+</xsdtest>
diff --git a/xsdtest.xsl b/xsdtest.xsl
new file mode 100644
index 0000000..ca47c73
--- /dev/null
+++ b/xsdtest.xsl
@@ -0,0 +1,235 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:strip-space elements="xsdtest datatype equiv class"/>
+
+<xsl:output indent="yes" encoding="utf-8"/>
+
+<xsl:template match="xsdtest">
+ <testSuite>
+ <xsl:apply-templates/>
+ </testSuite>
+</xsl:template>
+
+<xsl:template match="datatype">
+<testCase>
+<requires datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{@name}">
+ <xsl:for-each select="param">
+ <param name="{@name}"><xsl:value-of select="."/></param>
+ </xsl:for-each>
+ </data>
+</element>
+</correct>
+<xsl:apply-templates select="valid|invalid"/>
+</testCase>
+<xsl:apply-templates select="equiv/class|length|lessThan|incomparable"/>
+</xsl:template>
+
+<xsl:template match="valid">
+ <xsl:call-template name="valid"/>
+</xsl:template>
+
+<xsl:template match="invalid">
+ <xsl:call-template name="invalid"/>
+</xsl:template>
+
+<xsl:template name="valid">
+ <valid>
+ <xsl:apply-templates select="@internalSubset"/>
+ <doc>
+ <xsl:copy-of select="namespace::*"/>
+ <xsl:value-of select="."/>
+ </doc>
+ </valid>
+</xsl:template>
+
+<xsl:template name="invalid">
+ <invalid>
+ <xsl:apply-templates select="@internalSubset"/>
+ <doc>
+ <xsl:copy-of select="namespace::*"/>
+ <xsl:value-of select="."/>
+ </doc>
+ </invalid>
+</xsl:template>
+
+<xsl:template match="@internalSubset">
+ <xsl:param name="doc" select="'doc'"/>
+ <xsl:attribute name="dtd">
+ <xsl:text>
+&lt;!DOCTYPE </xsl:text>
+ <xsl:value-of select="$doc"/>
+ <xsl:text> [
+</xsl:text>
+ <xsl:value-of select="."/>
+ <xsl:text>
+]></xsl:text>
+ </xsl:attribute>
+</xsl:template>
+
+<xsl:template match="class">
+<testCase>
+<correct>
+ <xsl:for-each select="value[1]">
+ <xsl:apply-templates select="@internalSubset">
+ <xsl:with-param name="doc">element</xsl:with-param>
+ </xsl:apply-templates>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <value>
+ <xsl:copy-of select="namespace::*"/>
+ <xsl:attribute name="type"><xsl:value-of select="../../../@name"/></xsl:attribute>
+ <xsl:value-of select="."/>
+ </value>
+ </element>
+ </xsl:for-each>
+</correct>
+<xsl:for-each select="value[position() != 1]">
+ <xsl:call-template name="valid"/>
+</xsl:for-each>
+<xsl:for-each select="preceding-sibling::class/value|following-sibling::class/value">
+ <xsl:call-template name="invalid"/>
+</xsl:for-each>
+</testCase>
+</xsl:template>
+
+<xsl:template match="length">
+<testCase>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="length"><xsl:value-of select="@value"/></param>
+ </data>
+</element>
+</correct>
+<xsl:call-template name="valid"/>
+</testCase>
+
+<testCase>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="length"><xsl:value-of select="@value + 1"/></param>
+ </data>
+</element>
+</correct>
+<xsl:call-template name="invalid"/>
+</testCase>
+
+<xsl:if test="@value != 0">
+ <testCase>
+ <correct>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="length"><xsl:value-of select="@value - 1"/></param>
+ </data>
+ </element>
+ </correct>
+ <xsl:call-template name="invalid"/>
+ </testCase>
+</xsl:if>
+
+</xsl:template>
+
+<xsl:template match="lessThan">
+<testCase>
+<correct>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="minExclusive">
+ <xsl:value-of select="value[1]"/>
+ </param>
+ </data>
+ </element>
+</correct>
+<valid>
+<doc>
+<xsl:value-of select="value[2]"/>
+</doc>
+</valid>
+<invalid>
+<doc>
+<xsl:value-of select="value[1]"/>
+</doc>
+</invalid>
+</testCase>
+<testCase>
+<correct>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="minExclusive">
+ <xsl:value-of select="value[2]"/>
+ </param>
+ </data>
+ </element>
+</correct>
+<invalid>
+<doc>
+<xsl:value-of select="value[1]"/>
+</doc>
+</invalid>
+<invalid>
+<doc>
+<xsl:value-of select="value[2]"/>
+</doc>
+</invalid>
+</testCase>
+</xsl:template>
+
+<xsl:template match="incomparable">
+<testCase>
+<correct>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="minExclusive">
+ <xsl:value-of select="value[1]"/>
+ </param>
+ </data>
+ </element>
+</correct>
+<invalid>
+<doc>
+<xsl:value-of select="value[2]"/>
+</doc>
+</invalid>
+<invalid>
+<doc>
+<xsl:value-of select="value[1]"/>
+</doc>
+</invalid>
+</testCase>
+<testCase>
+<correct>
+ <element xmlns="http://relaxng.org/ns/structure/1.0" name="doc"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="{../@name}">
+ <param name="minExclusive">
+ <xsl:value-of select="value[2]"/>
+ </param>
+ </data>
+ </element>
+</correct>
+<invalid>
+<doc>
+<xsl:value-of select="value[1]"/>
+</doc>
+</invalid>
+<invalid>
+<doc>
+<xsl:value-of select="value[2]"/>
+</doc>
+</invalid>
+</testCase>
+</xsl:template>
+
+</xsl:stylesheet>