From ec8daa16bf59a43989160ec0b98b28838b1f0655 Mon Sep 17 00:00:00 2001
From: dkuhlman <none@none>
Date: Wed, 8 Oct 2014 16:07:14 -0700
Subject: [PATCH] Added generation of simpleType validators from XML schema

---
 README                                   |    8 +-
 generateDS.html                          |   31 +-
 generateDS.py                            |  372 +++---
 generateDS.txt                           |   28 +-
 gui/generateds_gui.py                    |    2 +-
 librarytemplate_howto.html               |    6 +-
 librarytemplate_howto.txt                |    2 +-
 process_includes.py                      |    5 +-
 setup.py                                 |    2 +-
 tests/OnePer/oneperType00_1One.py        |    5 +
 tests/OnePer/oneperType00_2One.py        |    5 +
 tests/OnePer/oneperType01_1One.py        |    5 +
 tests/OnePer/oneperType01_2One.py        |    5 +
 tests/OnePer/oneperType02_1One.py        |    5 +
 tests/OnePer/oneperType02_2One.py        |    5 +
 tests/OnePer/oneperType03_1One.py        |    5 +
 tests/OnePer/oneperType03_2One.py        |    5 +
 tests/abstract_type1_sup.py              |    5 +
 tests/abstract_type2_sup.py              |    5 +
 tests/annotations1_sup.py                |    5 +
 tests/annotations2_sup.py                |    5 +
 tests/anonymous_type.xsd                 |    6 +
 tests/anonymous_type1_sup.py             |   26 +-
 tests/anonymous_type2_sup.py             |   26 +-
 tests/anysimpletype1_sup.py              |    5 +
 tests/anysimpletype2_sup.py              |    5 +
 tests/anywildcard1_sup.py                |    5 +
 tests/anywildcard2_sup.py                |    5 +
 tests/attr_groups1_sup.py                |    5 +
 tests/attr_groups2_sup.py                |    5 +
 tests/extensions1_sup.py                 |   27 +-
 tests/extensions2_sup.py                 |   27 +-
 tests/mapcleanname1_sup.py               |    5 +
 tests/mapcleanname2_sup.py               |    5 +
 tests/out1_sup.py                        |   16 +-
 tests/out2_sup.py                        |   16 +-
 tests/people_procincl1_sup.py            |   16 +-
 tests/people_procincl2_sup.py            |   16 +-
 tests/prefix_classname1_sup.py           |   16 +-
 tests/prefix_classname2_sup.py           |   16 +-
 tests/recursive_simpletype1_sup.py       |    5 +
 tests/recursive_simpletype2_sup.py       |    5 +
 tests/simplecontent_restriction1_sup.py  |    5 +
 tests/simplecontent_restriction2_sup.py  |    5 +
 tests/simpletype_memberspecs1_sup.py     |    5 +
 tests/simpletype_memberspecs2_sup.py     |    5 +
 tests/simpletypes_other1_sup.py          |    5 +
 tests/simpletypes_other2_sup.py          |    5 +
 tests/test.py                            |   34 +-
 tests/to_etree.xsd                       |    1 -
 tests/to_etree1_sup.py                   |   27 +-
 tests/to_etree2_sup.py                   |   27 +-
 tests/validate_simpletypes.xml           |   28 +
 tests/validate_simpletypes.xsd           |   93 ++
 tests/validate_simpletypes1_out.xml      |   30 +
 tests/validate_simpletypes1_sub.py       |  235 ++++
 tests/validate_simpletypes1_sup.py       | 1396 ++++++++++++++++++++++
 tests/validate_simpletypes1_warnings.txt |   20 +
 tests/validate_simpletypes2_out.xml      |   30 +
 tests/validate_simpletypes2_sub.py       |  235 ++++
 tests/validate_simpletypes2_sup.py       | 1396 ++++++++++++++++++++++
 tests/validate_simpletypes2_warnings.txt |   20 +
 tutorial/generateds_tutorial.html        |    6 +-
 tutorial/generateds_tutorial.txt         |    2 +-
 tutorial/generateds_tutorial.zip         |  Bin 48761 -> 48764 bytes
 65 files changed, 4181 insertions(+), 203 deletions(-)
 create mode 100644 tests/validate_simpletypes.xml
 create mode 100644 tests/validate_simpletypes.xsd
 create mode 100644 tests/validate_simpletypes1_out.xml
 create mode 100644 tests/validate_simpletypes1_sub.py
 create mode 100644 tests/validate_simpletypes1_sup.py
 create mode 100644 tests/validate_simpletypes1_warnings.txt
 create mode 100644 tests/validate_simpletypes2_out.xml
 create mode 100644 tests/validate_simpletypes2_sub.py
 create mode 100644 tests/validate_simpletypes2_sup.py
 create mode 100644 tests/validate_simpletypes2_warnings.txt

diff --git a/README b/README
index 198b2e5..61e09eb 100644
--- a/README
+++ b/README
@@ -141,9 +141,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 Change history
 --------------
 
-Version 2.13b (09/14/2014)
+Version 2.14a (10/08/2014)
 - Fixed export of simpleType lists (added "' '.join(data)".  Thanks
   to Per Rosengren for catching this.
+- Added new style validation of simpleType data.  Validation
+  requirements are captured from the XML schema definition of the
+  simpleType, e.g. 'restriction base="..."' etc.  Thanks to
+  azer gh for implementing this extended capability.
+- Added unit test for simpleType validation, including test for
+  proper detection of bad (invalid) data.
 
 Version 2.13a (09/09/2014)
 - Minor fix to function generateToEtreeChildren.  Must generate
diff --git a/generateDS.html b/generateDS.html
index 4ed9fd4..90dfb32 100644
--- a/generateDS.html
+++ b/generateDS.html
@@ -205,7 +205,7 @@ ul.auto-toc {
 <tr><th class="docinfo-name">Author:</th>
 <td>Dave Kuhlman</td></tr>
 <tr><th class="docinfo-name">Contact:</th>
-<td><a class="first last reference external" href="mailto:dkuhlman&#64;davekuhlman.org">dkuhlman&#64;davekuhlman.org</a></td></tr>
+<td>dkuhlman (at) davekuhlman (dot) org</td></tr>
 <tr><th class="docinfo-name">Address:</th>
 <td><pre class="address">
 <a class="first last reference external" href="http://www.davekuhlman.org">http://www.davekuhlman.org</a>
@@ -220,7 +220,7 @@ They are used by updateversion.py. -->
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.13a</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.14a</td>
 </tr>
 </tbody>
 </table>
@@ -229,7 +229,7 @@ They are used by updateversion.py. -->
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">date:</th><td class="field-body">September 09, 2014</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">October 08, 2014</td>
 </tr>
 </tbody>
 </table>
@@ -552,6 +552,11 @@ Options:
                              module. Default=&quot;???&quot;
     --validator-bodies=path  Path to a directory containing files that provide
                              bodies (implementations) of validator methods.
+    --use-old-simpletype-validators
+                             Use the old style simpleType validator functions
+                             stored in a specified directory, instead of the
+                             new style validators generated directly from the
+                             XML schema.  See option --validator-bodies.
     --use-getter-setter      Generate getter and setter methods.  Values:
                              &quot;old&quot; - Name getters/setters getVar()/setVar().
                              &quot;new&quot; - Name getters/setters get_var()/set_var().
@@ -729,6 +734,17 @@ an optional &quot;.py&quot; extension.  If a file is not provided for a
 given type, an empty body (<tt class="docutils literal">pass</tt>) is generated.  In these
 files, lines with &quot;##&quot; in the first two columns are ignored
 and are not inserted.</dd>
+<dt>use-old-simpletype-validators</dt>
+<dd><tt class="docutils literal">generateDS.py</tt> is capable of generating validator bodies --
+the code that validates data content in an XML instance
+docuement and writes out warning messages if that data does not
+satisfy the facets in the <tt class="docutils literal">xs:restriction</tt> in the
+<tt class="docutils literal">xs:simpleType</tt> defintion in the XML schema.  Use this option
+if you want to use your own validation bodies/code defined in a
+specified directory .  See option <tt class="docutils literal"><span class="pre">--validator-bodies</span></tt> for
+information on that.  <em>Without</em> this option
+(<tt class="docutils literal"><span class="pre">--use-old-simpletype-validators</span></tt>), the validator code will
+be generated directly from the XML schema, which is the default.</dd>
 <dt>use-getter-setter</dt>
 <dd><p class="first"><tt class="docutils literal">generateDS.py</tt> now generates getter and setter methods (for
 variable &quot;abc&quot;, for example) with the names get_abc() and
@@ -761,7 +777,12 @@ changes to the generated python code.</dd>
 <dd>Do not process included XML Schema files.  By default,
 generateDS.py will insert content from files referenced by
 <tt class="docutils literal">&lt;include ... /&gt;</tt> elements into the XML Schema to be processed.
-See section <a class="reference internal" href="#include-file-processing">Include file processing</a>.</dd>
+See section <a class="reference internal" href="#include-file-processing">Include file processing</a>.  Note that include
+processing, which is performed in <tt class="docutils literal">process_includes.py</tt> is
+required for generating validator bodies from the XML schema,
+because the Lxml ElementTree produced in <tt class="docutils literal">process_includes.py</tt>
+is needed to generate the validator code.  So, using this option
+also turns off automatic generation of validator code.</dd>
 <dt>silence</dt>
 <dd>Normally, the code generated with generateDS echoes the
 information being parsed. To prevent the echo from occurring,
@@ -2886,7 +2907,7 @@ following among others:</p>
 <div class="footer">
 <hr class="footer" />
 <a class="reference external" href="generateDS.txt">View document source</a>.
-Generated on: 2014-09-09 20:05 UTC.
+Generated on: 2014-10-08 22:22 UTC.
 Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
 
 </div>
diff --git a/generateDS.py b/generateDS.py
index 12f65cd..145f995 100755
--- a/generateDS.py
+++ b/generateDS.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 """
 Synopsis:
-    Generate Python classes from XML Schema definition.
+    Generate Python classes from XML schema definition.
     Input is read from in_xsd_file or, if "-" (dash) arg, from stdin.
     Output is written to files named in "-o" and "-s" options.
 Usage:
@@ -35,6 +35,11 @@ Options:
                              module. Default="???"
     --validator-bodies=path  Path to a directory containing files that provide
                              bodies (implementations) of validator methods.
+    --use-old-simpletype-validators
+                             Use the old style simpleType validator functions
+                             stored in a specified directory, instead of the
+                             new style validators generated directly from the
+                             XML schema.  See option --validator-bodies.
     --use-getter-setter      Generate getter and setter methods.  Values:
                              "old" - Name getters/setters getVar()/setVar().
                              "new" - Name getters/setters get_var()/set_var().
@@ -51,10 +56,10 @@ Options:
                              generated files. This is useful if you want
                              to minimize the amount of (no-operation)
                              changes to the generated python code.
-    --no-process-includes    Do not process included XML Schema files.  By
+    --no-process-includes    Do not process included XML schema files.  By
                              default, generateDS.py will insert content
                              from files referenced by <include ... />
-                             elements into the XML Schema to be processed.
+                             elements into the XML schema to be processed.
     --silence                Normally, the code generated with generateDS
                              echoes the information being parsed. To prevent
                              the echo from occurring, use the --silence switch.
@@ -148,11 +153,6 @@ import keyword
 import StringIO
 import textwrap
 
-
-
-#sorry :couldnt pass the filename but with global variable,as i want to use it in validations try to correct this
-xsdFileName=[]
-
 # Default logger configuration
 logging.basicConfig(
     level=logging.DEBUG,
@@ -184,11 +184,14 @@ logging.disable(logging.INFO)
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.13b'
+VERSION = '2.14a'
 ##VERSION##
 
 GenerateProperties = 0
 UseGetterSetter = 'new'
+UseOldSimpleTypeValidators = False
+SchemaLxmlTree = None
+XsdFileName=[]
 MemberSpecs = None
 DelayedElements = set()
 DelayedElements_subclass = set()
@@ -3933,9 +3936,11 @@ def generateCtor(wrt, prefix, element):
                     wrt('            self.%s = %s\n' % (name, name))
                 else:
                     wrt('        self.%s = %s\n' % (name, name))
-                    #azg: validate if it is a simple type: validation shows warning so no fear that an error would rise
+                    # validate if it is a simple type.  Validation shows
+                    # a warning so no fear that an error would rise.
                     if (child.getSimpleType()):
-                        wrt('        self.validate_%s(self.%s)\n' % (child.getSimpleType(), name))
+                        wrt('        self.validate_%s(self.%s)\n' % (
+                            child.getSimpleType(), name))
     eltype = element.getType()
     if (element.getSimpleContent() or
             element.isMixed() or
@@ -3951,145 +3956,197 @@ def generateCtor(wrt, prefix, element):
 # end generateCtor
 
 
-#validate directly from xsd file, no need to specify directory for validation
-def getValidatorBody(stName,typexs,base):    
-#azg 
-    
-    az_s1 = '        if value is not None and all_validtion:\n'
-    from lxml import etree
-    ns = {'xs': 'http://www.w3.org/2001/XMLSchema'}
-    file = xsdFileName[0]
-    tree = etree.parse(file)
-    ns= {"xs": "http://www.w3.org/2001/XMLSchema"}
-
-    #on determine l elemnt ou le type est definit  
-    bases = tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]",namespaces=ns,n=stName,b=base)
-    enumerations = []
-    #une liste qui contient les restrictions deja traitees  
-    already_processed=[]
-    for restriction in bases[0]:
-        restriction_name = restriction.tag
-        if 'pattern' in  restriction_name and 'pattern' not in already_processed:
-            pattern =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:pattern/@value",namespaces=ns,n=stName,b=base)[0]
-            #convertir en string si le type n est pas string (car on ne peut pas comparer un pattern qu avec un type string
-            valuestring ='(str(value))'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='(value)'
-                toencode = '% {"value" : value}.encode("utf-8")'
-            az_s1+="           a = re_.compile('%(pattern)s')\n" %{"pattern": pattern}
-            az_s1+="           if not a.match%(valuestring)s:\n" % {"valuestring":valuestring}
-            az_s1+="              warnings.warn('Value %(val)s dosent match xsd pattern restriction on %(typename)s' %(express)s )\n" %{ "val":'%(value)s' , "typename" : stName, "express": toencode }
-            already_processed.append('pattern')
-        elif 'enumeration' in  restriction_name and 'enumeration' not in already_processed:
-            enumerations =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:enumeration/@value",namespaces=ns,n=stName,b=base)          
-            already_processed.append('enumeration')
-            if len(enumerations)>0:
-                az_s1+="           enumerations=%(enumerations)s\n" % {'enumerations' : enumerations}
-                az_s1+="           enumeration_respectee = False\n"
-                az_s1+="           for enum in enumerations:\n"
-                az_s1+="               if value == enum:\n"    
-                az_s1+="                   enumeration_respectee=True\n"    
-                az_s1+="                   break\n"    
-                az_s1+="           if not enumeration_respectee:\n"
-                az_s1+="               warnings.warn('Value %(val)s dosent match xsd enumeration restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": '% {"value" : value.encode("utf-8")}'}
-        elif 'maxLength' in  restriction_name and 'maxLength' not in already_processed:
-            valuestring ='(str(value))'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='(value)' 
-                toencode = '% {"value" : value}.encode("utf-8")'          
-            maxLength =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:maxLength/@value",namespaces=ns,n=stName,b=base)[0]          
-            az_s1+="           if len%(valuestring)s > %(maxLength)s:\n" % {'maxLength' : maxLength, "valuestring" :valuestring}
-            az_s1+="               warnings.warn('Value %(val)s dosent match xsd maxLength restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode}
-        elif 'minLength' in  restriction_name and 'minLength' not in already_processed:
-            valuestring ='(str(value))'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='(value)' 
-                toencode = '% {"value" : value}.encode("utf-8")'          
-            minLength =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:minLength/@value",namespaces=ns,n=stName,b=base)[0]          
-            az_s1+="           if len%(valuestring)s < %(minLength)s:\n" % {'minLength' : minLength, "valuestring" :valuestring}
-            az_s1+="               warnings.warn('Value %(val)s dosent match xsd minLength restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode}
-            already_processed.append('minLength')
-        elif 'minInclusive' in  restriction_name and 'minInclusive' not in already_processed:
-            valuestring ='(value)'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='len(str(value))' 
-                toencode = '% {"value" : value}.encode("utf-8")'          
-            minInclusive =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:minInclusive/@value",namespaces=ns,n=stName,b=base)[0]          
-            az_s1+="           if %(valuestring)s <= %(minInclusive)s:\n" % {'minInclusive' : minInclusive, "valuestring" :valuestring}
-            az_s1+="               warnings.warn('Value %(val)s dosent match xsd minInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
-            already_processed.append('minInclusive')
-        elif 'maxInclusive' in  restriction_name and 'maxInclusive' not in already_processed:
-            valuestring ='(value)'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='len(str(value))' 
-                toencode = '% {"value" : value}.encode("utf-8")'          
-            maxInclusive =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:maxInclusive/@value",namespaces=ns,n=stName,b=base)[0]          
-            az_s1+="           if %(valuestring)s >= %(maxInclusive)s:\n" % {'maxInclusive' : maxInclusive, "valuestring" :valuestring}
-            az_s1+="               warnings.warn('Value %(val)s dosent match xsd maxInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
-            already_processed.append('maxInclusive')
-        elif 'totalDigits' in  restriction_name and 'totalDigits' not in already_processed:
-            valuestring ='(str(value))'
-            toencode = '% {"value" : value}'
-            if 'string' in base:
-                valuestring ='(value)' 
-                toencode = '% {"value" : value}.encode("utf-8")'          
-            totalDigits =tree.xpath("//xs:simpleType[@name=$n]/xs:restriction[@base=$b]/xs:totalDigits/@value",namespaces=ns,n=stName,b=base)[0]          
-            az_s1+="           if len%(valuestring)s >= %(totalDigits)s:\n" % {'totalDigits' : totalDigits, "valuestring" :valuestring}
-            az_s1+="               warnings.warn('Value %(val)s dosent match xsd maxInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
-            already_processed.append('totalDigits')
-    
-    
-    
-        
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    
-    az_s1+= '           pass\n'
-    
-    
-    return az_s1
-
-#/azg    
-    
-    
-    
-    
-    
-    retrieved = 0
-    if ValidatorBodiesBasePath:
-        found = 0
-        path = '%s%s%s.py' % (ValidatorBodiesBasePath, os.sep, stName, )
-        if os.path.exists(path):
-            found = 1
+# find the simple type, either a named simpleType or an anonymous one.
+def find_simple_type_def(tree, stName, element, child, ns, base):
+    st = None
+    if stName:
+        st_defs = tree.xpath("//xs:simpleType[@name=$n]", namespaces=ns, n=stName)
+        if st_defs:
+            st = st_defs[0]
         else:
-            path = '%s%s%s' % (ValidatorBodiesBasePath, os.sep, stName, )
+            typeName = element.getType()
+            childName = child.getName()
+            # search for an anonymous simpleType.
+            el_defs = tree.xpath("//xs:complexType[@name=$typeName]//xs:element[@name=$childName]/xs:simpleType",
+                namespaces=ns, typeName=typeName, childName=childName)
+            if el_defs:
+                st = el_defs[0]
+            else:
+                # search for an anonymous simpleType inside an anonymous complexType.
+                el_defs = tree.xpath("//xs:element[@name=$typeName]/xs:complexType//xs:element[@name=$childName]/xs:simpleType",
+                    namespaces=ns, typeName=typeName, childName=childName)
+    return st
+
+
+#validate directly from xsd file, no need to specify directory for validation
+def getValidatorBody(stName, base, element, child):
+    if not UseOldSimpleTypeValidators and SchemaLxmlTree is not None:
+        # generate validator bodies directly from the XML schema.
+        s1 = '        if value is not None and Validate_simpletypes_:\n'
+        initial_len = len(s1)
+        ns = {'xs': 'http://www.w3.org/2001/XMLSchema'}
+        fileName = XsdFileName[0]
+        tree = SchemaLxmlTree
+        ns= {"xs": "http://www.w3.org/2001/XMLSchema"}
+        #on determine l elemnt ou le type est definit  
+        st = find_simple_type_def(tree, stName, element, child, ns, base)
+        if st is not None:
+            bases = st.xpath("xs:restriction[@base=$b]", namespaces=ns, n=stName, b=base)
+            #une liste qui contient les restrictions deja traitees  
+            already_processed=[]
+            if bases:
+                for restriction in bases[0]:
+                    restriction_name = restriction.tag
+                    if 'pattern' in restriction_name and 'pattern' not in already_processed:
+                        pattern = st.xpath("xs:restriction[@base=$b]/xs:pattern/@value", namespaces=ns, n=stName, b=base)
+                        if pattern:
+                            pattern = pattern[0]
+                            already_processed.append('pattern')
+                            #convertir en string si le type n est pas string (car on ne peut pas comparer un pattern qu avec un type string
+                            valuestring ='(str(value))'
+                            toencode = '% {"value" : value}'
+                            if 'string' in base:
+                                valuestring = '(value)'
+                                toencode = '% {"value" : value.encode("utf-8")}'
+                            s1 += "           a = re_.compile('%(pattern)s')\n" %{"pattern": pattern}
+                            s1 += "           if not a.match%(valuestring)s:\n" % {"valuestring":valuestring}
+                            s1 += "              warnings.warn('Value \"%(val)s\" does not match xsd pattern restriction on %(typename)s' %(express)s )\n" %{ "val":'%(value)s' , "typename" : stName, "express": toencode }
+                    elif 'enumeration' in restriction_name and 'enumeration' not in already_processed:
+                        enumerations = st.xpath("xs:restriction[@base=$b]/xs:enumeration/@value", namespaces=ns, n=stName, b=base)
+                        if enumerations:
+                            already_processed.append('enumeration')
+                            s1 += "           enumerations = %(enumerations)s\n" % {'enumerations' : enumerations}
+                            s1 += "           enumeration_respectee = False\n"
+                            s1 += "           for enum in enumerations:\n"
+                            s1 += "               if value == enum:\n"
+                            s1 += "                   enumeration_respectee = True\n"
+                            s1 += "                   break\n"
+                            s1 += "           if not enumeration_respectee:\n"
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd enumeration restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": '% {"value" : value.encode("utf-8")}'}
+                    elif 'maxLength' in restriction_name and 'maxLength' not in already_processed:
+                        valuestring = '(str(value))'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = '(value)' 
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        maxLength = st.xpath("xs:restriction[@base=$b]/xs:maxLength/@value", namespaces=ns, n=stName, b=base)
+                        if maxLength:
+                            maxLength = maxLength[0]
+                            already_processed.append('maxLength')
+                            s1 += "           if len%(valuestring)s > %(maxLength)s:\n" % {'maxLength' : maxLength, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd maxLength restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode}
+                    elif 'minLength' in restriction_name and 'minLength' not in already_processed:
+                        valuestring = '(str(value))'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = '(value)' 
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        minLength = st.xpath("xs:restriction[@base=$b]/xs:minLength/@value", namespaces=ns, n=stName, b=base)
+                        if minLength:
+                            minLength = minLength[0]
+                            already_processed.append('minLength')
+                            s1 += "           if len%(valuestring)s < %(minLength)s:\n" % {'minLength' : minLength, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd minLength restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode}
+                    elif 'length' in restriction_name and 'length' not in already_processed:
+                        valuestring = '(str(value))'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = '(value)' 
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        length = st.xpath("xs:restriction[@base=$b]/xs:length/@value", namespaces=ns, n=stName, b=base)
+                        if length:
+                            length = length[0]
+                            already_processed.append('length')
+                            s1 += "           if len%(valuestring)s != %(length)s:\n" % {'length' : length, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd length restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode}
+                    elif 'minInclusive' in  restriction_name and 'minInclusive' not in already_processed:
+                        valuestring = 'value'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = 'len(str(value))'
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        minInclusive = st.xpath("xs:restriction[@base=$b]/xs:minInclusive/@value", namespaces=ns, n=stName, b=base)
+                        if minInclusive:
+                            minInclusive = minInclusive[0]
+                            already_processed.append('minInclusive')
+                            s1 += "           if %(valuestring)s <= %(minInclusive)s:\n" % {'minInclusive' : minInclusive, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd minInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
+                    elif 'maxInclusive' in  restriction_name and 'maxInclusive' not in already_processed:
+                        valuestring = 'value'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = 'len(str(value))'
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        maxInclusive = st.xpath("xs:restriction[@base=$b]/xs:maxInclusive/@value", namespaces=ns, n=stName, b=base)
+                        if maxInclusive:
+                            maxInclusive = maxInclusive[0]
+                            already_processed.append('maxInclusive')
+                            s1 += "           if %(valuestring)s >= %(maxInclusive)s:\n" % {'maxInclusive' : maxInclusive, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd maxInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
+                    elif 'minExclusive' in  restriction_name and 'minExclusive' not in already_processed:
+                        valuestring = 'value'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = 'len(str(value))'
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        minExclusive = st.xpath("xs:restriction[@base=$b]/xs:minExclusive/@value", namespaces=ns, n=stName, b=base)
+                        if minExclusive:
+                            minExclusive = minExclusive[0]
+                            already_processed.append('minExclusive')
+                            s1 += "           if %(valuestring)s < %(minExclusive)s:\n" % {'minExclusive' : minExclusive, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd minExclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
+                    elif 'maxExclusive' in restriction_name and 'maxExclusive' not in already_processed:
+                        valuestring = 'value'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = 'len(str(value))'
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        maxExclusive = st.xpath("xs:restriction[@base=$b]/xs:maxExclusive/@value", namespaces=ns, n=stName, b=base)
+                        if maxExclusive:
+                            maxExclusive = maxExclusive[0]
+                            already_processed.append('maxExclusive')
+                            s1 += "           if %(valuestring)s > %(maxExclusive)s:\n" % {'maxExclusive' : maxExclusive, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd maxExclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
+                    elif 'totalDigits' in restriction_name and 'totalDigits' not in already_processed:
+                        valuestring = '(str(value))'
+                        toencode = '% {"value" : value}'
+                        if 'string' in base:
+                            valuestring = '(value)'
+                            toencode = '% {"value" : value.encode("utf-8")}'
+                        totalDigits = st.xpath("xs:restriction[@base=$b]/xs:totalDigits/@value", namespaces=ns, n=stName, b=base)
+                        if totalDigits:
+                            totalDigits = totalDigits[0]
+                            already_processed.append('totalDigits')
+                            s1 += "           if len%(valuestring)s >= %(totalDigits)s:\n" % {'totalDigits' : totalDigits, "valuestring" :valuestring}
+                            s1 += "               warnings.warn('Value \"%(val)s\" does not match xsd maxInclusive restriction on %(typename)s' %(express)s )\n" % {"val":'%(value)s' , "typename" : stName, "express": toencode }
+        if len(s1) == initial_len:
+            s1 += '           pass\n'
+        return s1
+    else:
+        # if UseOldSimpleTypeValidators -- generate validator bodies from use code.
+        retrieved = 0
+        if ValidatorBodiesBasePath:
+            found = 0
+            path = '%s%s%s.py' % (ValidatorBodiesBasePath, os.sep, stName, )
             if os.path.exists(path):
                 found = 1
-        if found:
-            infile = open(path, 'r')
-            lines = infile.readlines()
-            infile.close()
-            lines1 = []
-            for line in lines:
-                if not line.startswith('##'):
-                    lines1.append(line)
-            s1 = ''.join(lines1)
-            retrieved = 1
-    if not retrieved:
-        s1 = '        pass\n'
-    return s1
+            else:
+                path = '%s%s%s' % (ValidatorBodiesBasePath, os.sep, stName, )
+                if os.path.exists(path):
+                    found = 1
+            if found:
+                infile = open(path, 'r')
+                lines = infile.readlines()
+                infile.close()
+                lines1 = []
+                for line in lines:
+                    if not line.startswith('##'):
+                        lines1.append(line)
+                s1 = ''.join(lines1)
+                retrieved = 1
+        if not retrieved:
+            s1 = '        pass\n'
+        return s1
 # end getValidatorBody
 
 
@@ -4178,7 +4235,7 @@ def generateValidatorDefs(wrt, element):
                     (typeName, stObj.getBase(), ))
             else:
                 wrt('        # validate type %s\n' % (typeName, ))
-            wrt(getValidatorBody(typeName,child.getType(),stObj.getBase()))
+            wrt(getValidatorBody(typeName, stObj.getBase(), element, child))
     attrDefs = element.getAttributeDefs()
     for key in attrDefs:
         attrDef = attrDefs[key]
@@ -4194,7 +4251,7 @@ def generateValidatorDefs(wrt, element):
                     typeName, stObj.getBase(), ))
             else:
                 wrt('        # validate type %s\n' % (typeName, ))
-            wrt(getValidatorBody(typeName,attrDef.getType(),attrDef.getBase()))
+            wrt(getValidatorBody(typeName, stObj.getBase(), None, None))
 # end generateValidatorDefs
 
 
@@ -4430,9 +4487,10 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
 
 
-all_validtion = True
+Validate_simpletypes_ = True
 
 
 etree_ = None
@@ -6033,7 +6091,8 @@ def parseAndGenerate(
         processIncludes, options, args, superModule='???'):
     global DelayedElements, DelayedElements_subclass, \
         AlreadyGenerated, SaxDelayedElements, \
-        AlreadyGenerated_subclass, UserMethodsPath, UserMethodsModule
+        AlreadyGenerated_subclass, UserMethodsPath, UserMethodsModule, \
+        SchemaLxmlTree
     DelayedElements = set()
     DelayedElements_subclass = set()
     AlreadyGenerated = set()
@@ -6058,13 +6117,14 @@ def parseAndGenerate(
         if processIncludes:
             import process_includes
             outfile = StringIO.StringIO()
-            process_includes.process_include_files(
+            doc = process_includes.process_include_files(
                 infile, outfile,
                 inpath=xschemaFileName,
                 catalogpath=catalogFilename,
                 fixtypenames=FixTypeNames)
             outfile.seek(0)
             infile = outfile
+            SchemaLxmlTree = doc.getroot()
         parser.parse(infile)
         root = dh.getRoot()
         root.annotate()
@@ -6257,7 +6317,7 @@ def main():
         ExternalEncoding, MemberSpecs, NoQuestions, \
         ExportWrite, ExportEtree, ExportLiteral, \
         FixTypeNames, SingleFileOutput, OutputDirectory, \
-        ModuleSuffix
+        ModuleSuffix, UseOldSimpleTypeValidators
     outputText = True
     args = sys.argv[1:]
     try:
@@ -6273,7 +6333,7 @@ def main():
                 'no-questions', 'session=', 'fix-type-names=',
                 'version', 'export=',
                 'one-file-per-xsd', 'output-directory=',
-                'module-suffix='
+                'module-suffix=', 'use-old-simpletype-validators',
             ])
     except getopt.GetoptError:
         usage()
@@ -6392,6 +6452,8 @@ def main():
                 err_msg('*** Option use-getter-setter must '
                         '"old" or "new" or "none".\n')
                 sys.exit(1)
+        elif option[0] == '--use-old-simpletype-validators':
+            UseOldSimpleTypeValidators = True
         elif option[0] in ('-u', '--user-methods'):
             UserMethodsPath = option[1]
         elif option[0] == '--no-process-includes':
@@ -6444,7 +6506,7 @@ def main():
             usage()
         else:
             xschemaFileName = args[0]
-            xsdFileName.append(xschemaFileName)
+            XsdFileName.append(xschemaFileName)
     silent = not outputText
     TEMPLATE_MAIN = fixSilence(TEMPLATE_MAIN, silent)
     TEMPLATE_SUBCLASS_FOOTER = fixSilence(TEMPLATE_SUBCLASS_FOOTER, silent)
diff --git a/generateDS.txt b/generateDS.txt
index d8e2df5..ad40547 100644
--- a/generateDS.txt
+++ b/generateDS.txt
@@ -3,7 +3,7 @@ generateDS -- Generate Data Structures from XML Schema
 ======================================================
 
 :author: Dave Kuhlman
-:contact: dkuhlman@davekuhlman.org
+:contact: dkuhlman (at) davekuhlman (dot) org
 :address:
     http://www.davekuhlman.org
 
@@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema
 
 .. version
 
-:revision: 2.13b
+:revision: 2.14a
 
 .. version
 
@@ -253,6 +253,11 @@ Here is the usage message displayed by ``generateDS.py``::
                                  module. Default="???"
         --validator-bodies=path  Path to a directory containing files that provide
                                  bodies (implementations) of validator methods.
+        --use-old-simpletype-validators
+                                 Use the old style simpleType validator functions
+                                 stored in a specified directory, instead of the
+                                 new style validators generated directly from the
+                                 XML schema.  See option --validator-bodies.
         --use-getter-setter      Generate getter and setter methods.  Values:
                                  "old" - Name getters/setters getVar()/setVar().
                                  "new" - Name getters/setters get_var()/set_var().
@@ -442,6 +447,18 @@ validator-bodies=<path>
     files, lines with "##" in the first two columns are ignored
     and are not inserted.
 
+use-old-simpletype-validators
+    ``generateDS.py`` is capable of generating validator bodies --
+    the code that validates data content in an XML instance
+    docuement and writes out warning messages if that data does not
+    satisfy the facets in the ``xs:restriction`` in the
+    ``xs:simpleType`` defintion in the XML schema.  Use this option
+    if you want to use your own validation bodies/code defined in a
+    specified directory .  See option ``--validator-bodies`` for
+    information on that.  *Without* this option
+    (``--use-old-simpletype-validators``), the validator code will
+    be generated directly from the XML schema, which is the default.
+
 use-getter-setter
     ``generateDS.py`` now generates getter and setter methods (for
     variable "abc", for example) with the names get_abc() and
@@ -477,7 +494,12 @@ no-process-includes
     Do not process included XML Schema files.  By default,
     generateDS.py will insert content from files referenced by
     ``<include ... />`` elements into the XML Schema to be processed.
-    See section `Include file processing`_.
+    See section `Include file processing`_.  Note that include
+    processing, which is performed in ``process_includes.py`` is
+    required for generating validator bodies from the XML schema,
+    because the Lxml ElementTree produced in ``process_includes.py``
+    is needed to generate the validator code.  So, using this option
+    also turns off automatic generation of validator code.
 
 silence
     Normally, the code generated with generateDS echoes the
diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py
index 3e2bc3f..d0e31e8 100755
--- a/gui/generateds_gui.py
+++ b/gui/generateds_gui.py
@@ -31,7 +31,7 @@ from libgenerateDS.gui import generateds_gui_session
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.13b'
+VERSION = '2.14a'
 ##VERSION##
 
 
diff --git a/librarytemplate_howto.html b/librarytemplate_howto.html
index db0373e..fe92475 100644
--- a/librarytemplate_howto.html
+++ b/librarytemplate_howto.html
@@ -217,7 +217,7 @@ ul.auto-toc {
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.13a</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.14a</td>
 </tr>
 </tbody>
 </table>
@@ -226,7 +226,7 @@ ul.auto-toc {
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">date:</th><td class="field-body">September 09, 2014</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">October 08, 2014</td>
 </tr>
 </tbody>
 </table>
@@ -380,7 +380,7 @@ this command for your needs.  For example, you may need to use
 <div class="footer">
 <hr class="footer" />
 <a class="reference external" href="librarytemplate_howto.txt">View document source</a>.
-Generated on: 2014-09-09 19:14 UTC.
+Generated on: 2014-10-08 22:22 UTC.
 Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
 
 </div>
diff --git a/librarytemplate_howto.txt b/librarytemplate_howto.txt
index ed399ce..1c3c521 100644
--- a/librarytemplate_howto.txt
+++ b/librarytemplate_howto.txt
@@ -8,7 +8,7 @@ How to package a generateDS.py generated library
 
 .. version
 
-:revision: 2.13b
+:revision: 2.14a
 
 .. version
 
diff --git a/process_includes.py b/process_includes.py
index 8ea7785..166239b 100755
--- a/process_includes.py
+++ b/process_includes.py
@@ -30,7 +30,7 @@ from lxml import etree
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-VERSION = '2.13b'
+VERSION = '2.14a'
 ##VERSION##
 
 CatalogDict = {}
@@ -59,7 +59,8 @@ def process_include_files(
         'force': False,
         'fixtypenames': fixtypenames,
     })
-    prep_schema_doc(infile, outfile, inpath, options)
+    doc = prep_schema_doc(infile, outfile, inpath, options)
+    return doc
 
 
 def get_all_root_file_paths(infile, inpath='', catalogpath=None):
diff --git a/setup.py b/setup.py
index e73b0d4..6f85b8b 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@ setup(name="generateDS",
 # Do not modify the following VERSION comments.
 # Used by updateversion.py.
 ##VERSION##
-    version="2.13b",
+    version="2.14a",
 ##VERSION##
     author="Dave Kuhlman",
     author_email="dkuhlman@davekuhlman.org",
diff --git a/tests/OnePer/oneperType00_1One.py b/tests/OnePer/oneperType00_1One.py
index eb028c4..3691790 100644
--- a/tests/OnePer/oneperType00_1One.py
+++ b/tests/OnePer/oneperType00_1One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType00_2One.py b/tests/OnePer/oneperType00_2One.py
index eb028c4..3691790 100644
--- a/tests/OnePer/oneperType00_2One.py
+++ b/tests/OnePer/oneperType00_2One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType01_1One.py b/tests/OnePer/oneperType01_1One.py
index 96afe49..af63e67 100644
--- a/tests/OnePer/oneperType01_1One.py
+++ b/tests/OnePer/oneperType01_1One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType01_2One.py b/tests/OnePer/oneperType01_2One.py
index 96afe49..af63e67 100644
--- a/tests/OnePer/oneperType01_2One.py
+++ b/tests/OnePer/oneperType01_2One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType02_1One.py b/tests/OnePer/oneperType02_1One.py
index 63667bb..b2a8871 100644
--- a/tests/OnePer/oneperType02_1One.py
+++ b/tests/OnePer/oneperType02_1One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType02_2One.py b/tests/OnePer/oneperType02_2One.py
index 63667bb..b2a8871 100644
--- a/tests/OnePer/oneperType02_2One.py
+++ b/tests/OnePer/oneperType02_2One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType03_1One.py b/tests/OnePer/oneperType03_1One.py
index c3102f4..ef4bbbb 100644
--- a/tests/OnePer/oneperType03_1One.py
+++ b/tests/OnePer/oneperType03_1One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/OnePer/oneperType03_2One.py b/tests/OnePer/oneperType03_2One.py
index c3102f4..ef4bbbb 100644
--- a/tests/OnePer/oneperType03_2One.py
+++ b/tests/OnePer/oneperType03_2One.py
@@ -30,6 +30,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/abstract_type1_sup.py b/tests/abstract_type1_sup.py
index 7474797..5b2555f 100644
--- a/tests/abstract_type1_sup.py
+++ b/tests/abstract_type1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/abstract_type2_sup.py b/tests/abstract_type2_sup.py
index 7474797..5b2555f 100644
--- a/tests/abstract_type2_sup.py
+++ b/tests/abstract_type2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/annotations1_sup.py b/tests/annotations1_sup.py
index ba6a380..98b240a 100644
--- a/tests/annotations1_sup.py
+++ b/tests/annotations1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/annotations2_sup.py b/tests/annotations2_sup.py
index ba6a380..98b240a 100644
--- a/tests/annotations2_sup.py
+++ b/tests/annotations2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/anonymous_type.xsd b/tests/anonymous_type.xsd
index 271664f..a9bb07f 100644
--- a/tests/anonymous_type.xsd
+++ b/tests/anonymous_type.xsd
@@ -14,6 +14,8 @@
               <xs:element name="FooType">
                 <xs:simpleType>
                   <xs:restriction base="xs:string">
+                      <xs:minLength value="10"/>
+                      <xs:maxLength value="19"/>
                   </xs:restriction>
                 </xs:simpleType>
               </xs:element>
@@ -26,6 +28,8 @@
               <xs:element name="BarType">
                 <xs:simpleType>
                   <xs:restriction base="xs:string">
+                      <xs:minLength value="20"/>
+                      <xs:maxLength value="29"/>
                   </xs:restriction>
                 </xs:simpleType>
               </xs:element>
@@ -38,6 +42,8 @@
               <xs:element name="BazType">
                 <xs:simpleType>
                   <xs:restriction base="xs:string">
+                      <xs:minLength value="30"/>
+                      <xs:maxLength value="39"/>
                   </xs:restriction>
                 </xs:simpleType>
               </xs:element>
diff --git a/tests/anonymous_type1_sup.py b/tests/anonymous_type1_sup.py
index 21f333e..3d0bc3a 100644
--- a/tests/anonymous_type1_sup.py
+++ b/tests/anonymous_type1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -762,6 +767,7 @@ class FooType1(GeneratedsSuper):
     def __init__(self, FooType=None):
         self.original_tagname_ = None
         self.FooType = FooType
+        self.validate_FooTypeType(self.FooType)
     def factory(*args_, **kwargs_):
         if FooType1.subclass:
             return FooType1.subclass(*args_, **kwargs_)
@@ -772,7 +778,11 @@ class FooType1(GeneratedsSuper):
     def set_FooType(self, FooType): self.FooType = FooType
     def validate_FooTypeType(self, value):
         # Validate type FooTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 10:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 19:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.FooType is not None
@@ -847,6 +857,7 @@ class BarType2(GeneratedsSuper):
     def __init__(self, BarType=None):
         self.original_tagname_ = None
         self.BarType = BarType
+        self.validate_BarTypeType(self.BarType)
     def factory(*args_, **kwargs_):
         if BarType2.subclass:
             return BarType2.subclass(*args_, **kwargs_)
@@ -857,7 +868,11 @@ class BarType2(GeneratedsSuper):
     def set_BarType(self, BarType): self.BarType = BarType
     def validate_BarTypeType(self, value):
         # Validate type BarTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 20:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on BarTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 29:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on BarTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.BarType is not None
@@ -932,6 +947,7 @@ class BazType3(GeneratedsSuper):
     def __init__(self, BazType=None):
         self.original_tagname_ = None
         self.BazType = BazType
+        self.validate_BazTypeType(self.BazType)
     def factory(*args_, **kwargs_):
         if BazType3.subclass:
             return BazType3.subclass(*args_, **kwargs_)
@@ -942,7 +958,11 @@ class BazType3(GeneratedsSuper):
     def set_BazType(self, BazType): self.BazType = BazType
     def validate_BazTypeType(self, value):
         # Validate type BazTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 30:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on BazTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 39:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on BazTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.BazType is not None
diff --git a/tests/anonymous_type2_sup.py b/tests/anonymous_type2_sup.py
index 21f333e..3d0bc3a 100644
--- a/tests/anonymous_type2_sup.py
+++ b/tests/anonymous_type2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -762,6 +767,7 @@ class FooType1(GeneratedsSuper):
     def __init__(self, FooType=None):
         self.original_tagname_ = None
         self.FooType = FooType
+        self.validate_FooTypeType(self.FooType)
     def factory(*args_, **kwargs_):
         if FooType1.subclass:
             return FooType1.subclass(*args_, **kwargs_)
@@ -772,7 +778,11 @@ class FooType1(GeneratedsSuper):
     def set_FooType(self, FooType): self.FooType = FooType
     def validate_FooTypeType(self, value):
         # Validate type FooTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 10:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 19:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.FooType is not None
@@ -847,6 +857,7 @@ class BarType2(GeneratedsSuper):
     def __init__(self, BarType=None):
         self.original_tagname_ = None
         self.BarType = BarType
+        self.validate_BarTypeType(self.BarType)
     def factory(*args_, **kwargs_):
         if BarType2.subclass:
             return BarType2.subclass(*args_, **kwargs_)
@@ -857,7 +868,11 @@ class BarType2(GeneratedsSuper):
     def set_BarType(self, BarType): self.BarType = BarType
     def validate_BarTypeType(self, value):
         # Validate type BarTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 20:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on BarTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 29:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on BarTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.BarType is not None
@@ -932,6 +947,7 @@ class BazType3(GeneratedsSuper):
     def __init__(self, BazType=None):
         self.original_tagname_ = None
         self.BazType = BazType
+        self.validate_BazTypeType(self.BazType)
     def factory(*args_, **kwargs_):
         if BazType3.subclass:
             return BazType3.subclass(*args_, **kwargs_)
@@ -942,7 +958,11 @@ class BazType3(GeneratedsSuper):
     def set_BazType(self, BazType): self.BazType = BazType
     def validate_BazTypeType(self, value):
         # Validate type BazTypeType, a restriction on xs:string.
-        pass
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 30:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on BazTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 39:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on BazTypeType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.BazType is not None
diff --git a/tests/anysimpletype1_sup.py b/tests/anysimpletype1_sup.py
index 8965b08..d1d826b 100644
--- a/tests/anysimpletype1_sup.py
+++ b/tests/anysimpletype1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/anysimpletype2_sup.py b/tests/anysimpletype2_sup.py
index 8965b08..d1d826b 100644
--- a/tests/anysimpletype2_sup.py
+++ b/tests/anysimpletype2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/anywildcard1_sup.py b/tests/anywildcard1_sup.py
index 6fe4929..5fad0db 100644
--- a/tests/anywildcard1_sup.py
+++ b/tests/anywildcard1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/anywildcard2_sup.py b/tests/anywildcard2_sup.py
index 6fe4929..5fad0db 100644
--- a/tests/anywildcard2_sup.py
+++ b/tests/anywildcard2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/attr_groups1_sup.py b/tests/attr_groups1_sup.py
index 75755fe..ec108a2 100644
--- a/tests/attr_groups1_sup.py
+++ b/tests/attr_groups1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/attr_groups2_sup.py b/tests/attr_groups2_sup.py
index 75755fe..ec108a2 100644
--- a/tests/attr_groups2_sup.py
+++ b/tests/attr_groups2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/extensions1_sup.py b/tests/extensions1_sup.py
index 56df5a9..4b81152 100644
--- a/tests/extensions1_sup.py
+++ b/tests/extensions1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1011,6 +1016,7 @@ class simpleFactoidType(GeneratedsSuper):
     def __init__(self, relation=None):
         self.original_tagname_ = None
         self.relation = relation
+        self.validate_RelationType(self.relation)
     def factory(*args_, **kwargs_):
         if simpleFactoidType.subclass:
             return simpleFactoidType.subclass(*args_, **kwargs_)
@@ -1021,7 +1027,15 @@ class simpleFactoidType(GeneratedsSuper):
     def set_relation(self, relation): self.relation = relation
     def validate_RelationType(self, value):
         # Validate type RelationType, a restriction on RelationType2.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['down', 'add']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on RelationType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.relation is not None
@@ -1097,6 +1111,7 @@ class mixedFactoidType(GeneratedsSuper):
     def __init__(self, relation=None, valueOf_=None, mixedclass_=None, content_=None):
         self.original_tagname_ = None
         self.relation = relation
+        self.validate_RelationType(self.relation)
         self.valueOf_ = valueOf_
         if mixedclass_ is None:
             self.mixedclass_ = MixedContainer
@@ -1119,7 +1134,15 @@ class mixedFactoidType(GeneratedsSuper):
     def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_
     def validate_RelationType(self, value):
         # Validate type RelationType, a restriction on RelationType2.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['down', 'add']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on RelationType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.relation is not None or
diff --git a/tests/extensions2_sup.py b/tests/extensions2_sup.py
index 56df5a9..4b81152 100644
--- a/tests/extensions2_sup.py
+++ b/tests/extensions2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1011,6 +1016,7 @@ class simpleFactoidType(GeneratedsSuper):
     def __init__(self, relation=None):
         self.original_tagname_ = None
         self.relation = relation
+        self.validate_RelationType(self.relation)
     def factory(*args_, **kwargs_):
         if simpleFactoidType.subclass:
             return simpleFactoidType.subclass(*args_, **kwargs_)
@@ -1021,7 +1027,15 @@ class simpleFactoidType(GeneratedsSuper):
     def set_relation(self, relation): self.relation = relation
     def validate_RelationType(self, value):
         # Validate type RelationType, a restriction on RelationType2.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['down', 'add']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on RelationType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.relation is not None
@@ -1097,6 +1111,7 @@ class mixedFactoidType(GeneratedsSuper):
     def __init__(self, relation=None, valueOf_=None, mixedclass_=None, content_=None):
         self.original_tagname_ = None
         self.relation = relation
+        self.validate_RelationType(self.relation)
         self.valueOf_ = valueOf_
         if mixedclass_ is None:
             self.mixedclass_ = MixedContainer
@@ -1119,7 +1134,15 @@ class mixedFactoidType(GeneratedsSuper):
     def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_
     def validate_RelationType(self, value):
         # Validate type RelationType, a restriction on RelationType2.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['down', 'add']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on RelationType' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.relation is not None or
diff --git a/tests/mapcleanname1_sup.py b/tests/mapcleanname1_sup.py
index 9776f19..0d05b13 100644
--- a/tests/mapcleanname1_sup.py
+++ b/tests/mapcleanname1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/mapcleanname2_sup.py b/tests/mapcleanname2_sup.py
index 9776f19..0d05b13 100644
--- a/tests/mapcleanname2_sup.py
+++ b/tests/mapcleanname2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/out1_sup.py b/tests/out1_sup.py
index 0ce418c..3890019 100644
--- a/tests/out1_sup.py
+++ b/tests/out1_sup.py
@@ -28,6 +28,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1449,6 +1454,7 @@ class programmer(person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmer.subclass:
@@ -1496,7 +1502,15 @@ class programmer(person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/out2_sup.py b/tests/out2_sup.py
index 0ce418c..3890019 100644
--- a/tests/out2_sup.py
+++ b/tests/out2_sup.py
@@ -28,6 +28,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1449,6 +1454,7 @@ class programmer(person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmer.subclass:
@@ -1496,7 +1502,15 @@ class programmer(person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/people_procincl1_sup.py b/tests/people_procincl1_sup.py
index c2d2220..1c35379 100644
--- a/tests/people_procincl1_sup.py
+++ b/tests/people_procincl1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -2520,6 +2525,7 @@ class programmer(person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmer.subclass:
@@ -2565,7 +2571,15 @@ class programmer(person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/people_procincl2_sup.py b/tests/people_procincl2_sup.py
index c2d2220..1c35379 100644
--- a/tests/people_procincl2_sup.py
+++ b/tests/people_procincl2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -2520,6 +2525,7 @@ class programmer(person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmer.subclass:
@@ -2565,7 +2571,15 @@ class programmer(person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/prefix_classname1_sup.py b/tests/prefix_classname1_sup.py
index 96730d2..404810c 100644
--- a/tests/prefix_classname1_sup.py
+++ b/tests/prefix_classname1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1307,6 +1312,7 @@ class tomato_programmer(tomato_person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if tomato_programmer.subclass:
@@ -1354,7 +1360,15 @@ class tomato_programmer(tomato_person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/prefix_classname2_sup.py b/tests/prefix_classname2_sup.py
index 96730d2..404810c 100644
--- a/tests/prefix_classname2_sup.py
+++ b/tests/prefix_classname2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -1307,6 +1312,7 @@ class tomato_programmer(tomato_person):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if tomato_programmer.subclass:
@@ -1354,7 +1360,15 @@ class tomato_programmer(tomato_person):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
diff --git a/tests/recursive_simpletype1_sup.py b/tests/recursive_simpletype1_sup.py
index 956f2f6..b793ade 100644
--- a/tests/recursive_simpletype1_sup.py
+++ b/tests/recursive_simpletype1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/recursive_simpletype2_sup.py b/tests/recursive_simpletype2_sup.py
index 956f2f6..b793ade 100644
--- a/tests/recursive_simpletype2_sup.py
+++ b/tests/recursive_simpletype2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simplecontent_restriction1_sup.py b/tests/simplecontent_restriction1_sup.py
index 3c59aa9..817e86e 100644
--- a/tests/simplecontent_restriction1_sup.py
+++ b/tests/simplecontent_restriction1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simplecontent_restriction2_sup.py b/tests/simplecontent_restriction2_sup.py
index 3c59aa9..817e86e 100644
--- a/tests/simplecontent_restriction2_sup.py
+++ b/tests/simplecontent_restriction2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simpletype_memberspecs1_sup.py b/tests/simpletype_memberspecs1_sup.py
index 8dae63a..6bdaf95 100644
--- a/tests/simpletype_memberspecs1_sup.py
+++ b/tests/simpletype_memberspecs1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simpletype_memberspecs2_sup.py b/tests/simpletype_memberspecs2_sup.py
index 8dae63a..6bdaf95 100644
--- a/tests/simpletype_memberspecs2_sup.py
+++ b/tests/simpletype_memberspecs2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simpletypes_other1_sup.py b/tests/simpletypes_other1_sup.py
index 84e2ae7..a51ea60 100644
--- a/tests/simpletypes_other1_sup.py
+++ b/tests/simpletypes_other1_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/simpletypes_other2_sup.py b/tests/simpletypes_other2_sup.py
index 84e2ae7..a51ea60 100644
--- a/tests/simpletypes_other2_sup.py
+++ b/tests/simpletypes_other2_sup.py
@@ -29,6 +29,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
diff --git a/tests/test.py b/tests/test.py
index 5e965bc..90ee2b6 100755
--- a/tests/test.py
+++ b/tests/test.py
@@ -331,8 +331,8 @@ class GenTest(unittest.TestCase):
         cmd = 'diff %s1_sub.py %s2_sub.py' % (t_, t_, )
         result, err = self.execute(cmd)
         self.check_result(result, err, ())
-        cmdTempl = 'python tests/%s2_sup.py tests/ipo.xml > tests/%s2_out.xml'
-        cmd = cmdTempl % (t_, t_, )
+        cmdTempl = 'python tests/%s2_sup.py tests/%s.xml > tests/%s2_out.xml'
+        cmd = cmdTempl % (t_, t_, t_, )
         result, _ = self.execute(cmd, cwd='..')
         cmd = 'diff %s1_out.xml %s2_out.xml' % (t_, t_, )
         result, err = self.execute(cmd)
@@ -550,6 +550,36 @@ class GenTest(unittest.TestCase):
         result, err = self.execute(cmd)
         self.check_result(result, err, ())
 
+    def test_025_validate_simpletypes(self):
+        cmdTempl = (
+            'python generateDS.py --no-dates --no-versions '
+            '--member-specs=list -f '
+            '-o tests/%s2_sup.py -s tests/%s2_sub.py '
+            '--super=%s2_sup '
+            'tests/%s.xsd'
+        )
+        t_ = 'validate_simpletypes'
+        cmd = cmdTempl % (t_, t_, t_, t_, )
+        result, _ = self.execute(cmd, cwd='..')
+        cmd = 'diff %s1_sup.py %s2_sup.py' % (t_, t_, )
+        result, err = self.execute(cmd)
+        self.check_result(result, err, ('sys.stdout.write',))
+        cmd = 'diff %s1_sub.py %s2_sub.py' % (t_, t_, )
+        result, err = self.execute(cmd)
+        self.check_result(result, err, ())
+        cmdTempl = (
+            'python tests/%s2_sup.py tests/%s.xml > tests/%s2_out.xml '
+            '2> tests/%s2_warnings.txt'
+        )
+        cmd = cmdTempl % (t_, t_, t_, t_, )
+        result, _ = self.execute(cmd, cwd='..')
+        cmd = 'diff %s1_out.xml %s2_out.xml' % (t_, t_, )
+        result, err = self.execute(cmd)
+        self.check_result(result, err, ())
+        cmd = 'diff %s1_warnings.txt %s2_warnings.txt' % (t_, t_, )
+        result, err = self.execute(cmd)
+        self.check_result(result, err, ())
+
     def check_result(self, result, err, ignore_strings):
         self.failUnlessEqual(len(result), 0)
         self.failUnlessEqual(len(err), 0)
diff --git a/tests/to_etree.xsd b/tests/to_etree.xsd
index 71d2860..1324971 100644
--- a/tests/to_etree.xsd
+++ b/tests/to_etree.xsd
@@ -337,4 +337,3 @@
     </xs:complexType>
 
 </xs:schema>
-
diff --git a/tests/to_etree1_sup.py b/tests/to_etree1_sup.py
index 8d7435a..4fe09cd 100644
--- a/tests/to_etree1_sup.py
+++ b/tests/to_etree1_sup.py
@@ -31,6 +31,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -924,6 +929,7 @@ class personType(GeneratedsSuper):
             self.promoter = promoter
         self.description = description
         self.range_ = range_
+        self.validate_RangeType(self.range_)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if personType.subclass:
@@ -970,7 +976,8 @@ class personType(GeneratedsSuper):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_RangeType(self, value):
         # Validate type RangeType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.name is not None or
@@ -1212,6 +1219,7 @@ class programmerType(personType):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmerType.subclass:
@@ -1261,7 +1269,15 @@ class programmerType(personType):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
@@ -1532,7 +1548,8 @@ class paramType(GeneratedsSuper):
     def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_
     def validate_FlowType(self, value):
         # Validate type FlowType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.valueOf_
@@ -1624,6 +1641,7 @@ class python_programmerType(programmerType):
         self.gui_developer = _cast(bool, gui_developer)
         self.favorite_editor = favorite_editor
         self.flowvalue = flowvalue
+        self.validate_FlowType(self.flowvalue)
         self.drcs = drcs
     def factory(*args_, **kwargs_):
         if python_programmerType.subclass:
@@ -1645,7 +1663,8 @@ class python_programmerType(programmerType):
     def set_gui_developer(self, gui_developer): self.gui_developer = gui_developer
     def validate_FlowType(self, value):
         # Validate type FlowType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.favorite_editor is not None or
diff --git a/tests/to_etree2_sup.py b/tests/to_etree2_sup.py
index 8d7435a..4fe09cd 100644
--- a/tests/to_etree2_sup.py
+++ b/tests/to_etree2_sup.py
@@ -31,6 +31,11 @@ import getopt
 import re as re_
 import base64
 import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
 
 etree_ = None
 Verbose_import_ = False
@@ -924,6 +929,7 @@ class personType(GeneratedsSuper):
             self.promoter = promoter
         self.description = description
         self.range_ = range_
+        self.validate_RangeType(self.range_)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if personType.subclass:
@@ -970,7 +976,8 @@ class personType(GeneratedsSuper):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_RangeType(self, value):
         # Validate type RangeType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.name is not None or
@@ -1212,6 +1219,7 @@ class programmerType(personType):
         self.ellong = ellong
         self.elparam = elparam
         self.elarraytypes = elarraytypes
+        self.validate_ArrayTypes(self.elarraytypes)
         self.extensiontype_ = extensiontype_
     def factory(*args_, **kwargs_):
         if programmerType.subclass:
@@ -1261,7 +1269,15 @@ class programmerType(personType):
     def set_extensiontype_(self, extensiontype_): self.extensiontype_ = extensiontype_
     def validate_ArrayTypes(self, value):
         # Validate type ArrayTypes, a restriction on xs:NMTOKEN.
-        pass
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on ArrayTypes' % {"value" : value.encode("utf-8")} )
     def hasContent_(self):
         if (
             self.email is not None or
@@ -1532,7 +1548,8 @@ class paramType(GeneratedsSuper):
     def set_valueOf_(self, valueOf_): self.valueOf_ = valueOf_
     def validate_FlowType(self, value):
         # Validate type FlowType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.valueOf_
@@ -1624,6 +1641,7 @@ class python_programmerType(programmerType):
         self.gui_developer = _cast(bool, gui_developer)
         self.favorite_editor = favorite_editor
         self.flowvalue = flowvalue
+        self.validate_FlowType(self.flowvalue)
         self.drcs = drcs
     def factory(*args_, **kwargs_):
         if python_programmerType.subclass:
@@ -1645,7 +1663,8 @@ class python_programmerType(programmerType):
     def set_gui_developer(self, gui_developer): self.gui_developer = gui_developer
     def validate_FlowType(self, value):
         # Validate type FlowType, a restriction on xs:integer.
-        pass
+        if value is not None and Validate_simpletypes_:
+           pass
     def hasContent_(self):
         if (
             self.favorite_editor is not None or
diff --git a/tests/validate_simpletypes.xml b/tests/validate_simpletypes.xml
new file mode 100644
index 0000000..a4d15e9
--- /dev/null
+++ b/tests/validate_simpletypes.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<container>
+    <sample1>
+        <token_enum_value>float</token_enum_value>
+        <integer_range_incl_value>2</integer_range_incl_value>
+        <integer_range_excl_value>7</integer_range_excl_value>
+        <min_max_length_value>abc def ghi</min_max_length_value>
+        <length_value>0123456789</length_value>
+        <totaldigits_value>12.456</totaldigits_value>
+        <anonymous_float_value>2.2</anonymous_float_value>
+    </sample1>
+    <sample2_bad>
+        <token_enum_value>floatxx</token_enum_value>
+        <integer_range_incl_value>22</integer_range_incl_value>
+        <integer_range_excl_value>-40</integer_range_excl_value>
+        <min_max_length_value>mno pqr</min_max_length_value>
+        <length_value>012345</length_value>
+        <totaldigits_value>12.456789</totaldigits_value>
+        <anonymous_float_value>0.2</anonymous_float_value>
+    </sample2_bad>
+    <sample3_bad>
+        <integer_range_incl_value>-50</integer_range_incl_value>
+        <min_max_length_value>asdf asdf asdf adf asdf asdf</min_max_length_value>
+        <length_value>01234567890</length_value>
+        <totaldigits_value>12345678.45678901</totaldigits_value>
+        <anonymous_float_value>6.6</anonymous_float_value>
+    </sample3_bad>
+</container>
diff --git a/tests/validate_simpletypes.xsd b/tests/validate_simpletypes.xsd
new file mode 100644
index 0000000..35b3598
--- /dev/null
+++ b/tests/validate_simpletypes.xsd
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+    <xs:element name="container" type="containerType"/>
+
+    <xs:complexType name="containerType">
+        <xs:sequence>
+            <xs:element name="sample1" type="simpleOneType" maxOccurs="unbounded"/>
+            <xs:element name="sample2_bad" type="simpleOneType" maxOccurs="unbounded"/>
+            <xs:element name="sample3_bad" type="simpleOneType" maxOccurs="unbounded"/>
+            <xs:element name="sample2" type="simpleTwoType" maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="simpleOneType" mixed="0">
+        <xs:sequence>
+            <xs:element name="token_enum_value" type="token_enum_st"/>
+            <xs:element name="token_enum_value" type="token_enum_st"/>
+            <xs:element name="integer_range_incl_value" type="integer_range_incl_st"/>
+            <xs:element name="integer_range_excl_value" type="integer_range_excl_st"/>
+            <xs:element name="min_max_length_value" type="min_max_length_st"/>
+            <xs:element name="length_value" type="length_st"/>
+            <xs:element name="totaldigits_value" type="totaldigits_st"/>
+            <!-- Test for use of anonymous simple type. -->
+            <xs:element name="anonymous_float_value">
+                <xs:simpleType>
+                    <xs:restriction base="xs:float">
+                        <xs:minInclusive value="1.1"/>
+                        <xs:maxInclusive value="4.4"/>
+                    </xs:restriction>
+                </xs:simpleType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+    <!-- Test for use of an anonymous simple type inside an anonymous complexType. -->
+    <xs:element name="simpleTwoType">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="Foo">
+                    <xs:complexType>
+                        <xs:all>
+                            <xs:element name="FooType">
+                                <xs:simpleType>
+                                    <xs:restriction base="xs:string">
+                                        <xs:minLength value="12"/>
+                                        <xs:maxLength value="24"/>
+                                    </xs:restriction>
+                                </xs:simpleType>
+                            </xs:element>
+                        </xs:all>
+                    </xs:complexType>
+                </xs:element>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+    <xs:simpleType name="token_enum_st">
+        <xs:restriction base="xs:NMTOKEN">
+            <xs:enumeration value="float"/>
+            <xs:enumeration value="int"/>
+            <xs:enumeration value="Name"/>
+            <xs:enumeration value="token"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="integer_range_incl_st">
+        <xs:restriction base="xs:integer">
+            <xs:minInclusive value="-5"/>
+            <xs:maxInclusive value="10"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="integer_range_excl_st">
+        <xs:restriction base="xs:integer">
+            <xs:minExclusive value="-5"/>
+            <xs:maxExclusive value="10"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="min_max_length_st">
+        <xs:restriction base="xs:string">
+            <xs:minLength value="10"/>
+            <xs:maxLength value="20"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="length_st">
+        <xs:restriction base="xs:string">
+            <xs:length value="10"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="totaldigits_st">
+        <xs:restriction base="xs:float">
+            <xs:totalDigits value="15"/>
+            <xs:fractionDigits value="5"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/tests/validate_simpletypes1_out.xml b/tests/validate_simpletypes1_out.xml
new file mode 100644
index 0000000..70c8feb
--- /dev/null
+++ b/tests/validate_simpletypes1_out.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<container>
+    <sample1>
+        <token_enum_value>float</token_enum_value>
+        <token_enum_value>float</token_enum_value>
+        <integer_range_incl_value>2</integer_range_incl_value>
+        <integer_range_excl_value>7</integer_range_excl_value>
+        <min_max_length_value>abc def ghi</min_max_length_value>
+        <length_value>0123456789</length_value>
+        <totaldigits_value>12.456</totaldigits_value>
+        <anonymous_float_value>2.2</anonymous_float_value>
+    </sample1>
+    <sample2_bad>
+        <token_enum_value>floatxx</token_enum_value>
+        <token_enum_value>floatxx</token_enum_value>
+        <integer_range_incl_value>22</integer_range_incl_value>
+        <integer_range_excl_value>-40</integer_range_excl_value>
+        <min_max_length_value>mno pqr</min_max_length_value>
+        <length_value>012345</length_value>
+        <totaldigits_value>12.456789000000001</totaldigits_value>
+        <anonymous_float_value>0.2</anonymous_float_value>
+    </sample2_bad>
+    <sample3_bad>
+        <integer_range_incl_value>-50</integer_range_incl_value>
+        <min_max_length_value>asdf asdf asdf adf asdf asdf</min_max_length_value>
+        <length_value>01234567890</length_value>
+        <totaldigits_value>12345678.456789009273052</totaldigits_value>
+        <anonymous_float_value>6.6</anonymous_float_value>
+    </sample3_bad>
+</container>
diff --git a/tests/validate_simpletypes1_sub.py b/tests/validate_simpletypes1_sub.py
new file mode 100644
index 0000000..6b50bce
--- /dev/null
+++ b/tests/validate_simpletypes1_sub.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+
+#
+# Generated  by generateDS.py.
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-o', 'tests/validate_simpletypes2_sup.py')
+#   ('-s', 'tests/validate_simpletypes2_sub.py')
+#   ('--super', 'validate_simpletypes2_sup')
+#
+# Command line arguments:
+#   tests/validate_simpletypes.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --member-specs="list" -f -o "tests/validate_simpletypes2_sup.py" -s "tests/validate_simpletypes2_sub.py" --super="validate_simpletypes2_sup" tests/validate_simpletypes.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+
+import validate_simpletypes2_sup as supermod
+
+etree_ = None
+Verbose_import_ = False
+(
+    XMLParser_import_none, XMLParser_import_lxml,
+    XMLParser_import_elementtree
+) = range(3)
+XMLParser_import_library = None
+try:
+    # lxml
+    from lxml import etree as etree_
+    XMLParser_import_library = XMLParser_import_lxml
+    if Verbose_import_:
+        print("running with lxml.etree")
+except ImportError:
+    try:
+        # cElementTree from Python 2.5+
+        import xml.etree.cElementTree as etree_
+        XMLParser_import_library = XMLParser_import_elementtree
+        if Verbose_import_:
+            print("running with cElementTree on Python 2.5+")
+    except ImportError:
+        try:
+            # ElementTree from Python 2.5+
+            import xml.etree.ElementTree as etree_
+            XMLParser_import_library = XMLParser_import_elementtree
+            if Verbose_import_:
+                print("running with ElementTree on Python 2.5+")
+        except ImportError:
+            try:
+                # normal cElementTree install
+                import cElementTree as etree_
+                XMLParser_import_library = XMLParser_import_elementtree
+                if Verbose_import_:
+                    print("running with cElementTree")
+            except ImportError:
+                try:
+                    # normal ElementTree install
+                    import elementtree.ElementTree as etree_
+                    XMLParser_import_library = XMLParser_import_elementtree
+                    if Verbose_import_:
+                        print("running with ElementTree")
+                except ImportError:
+                    raise ImportError(
+                        "Failed to import ElementTree from any known place")
+
+
+def parsexml_(*args, **kwargs):
+    if (XMLParser_import_library == XMLParser_import_lxml and
+            'parser' not in kwargs):
+        # Use the lxml ElementTree compatible parser so that, e.g.,
+        #   we ignore comments.
+        kwargs['parser'] = etree_.ETCompatXMLParser()
+    doc = etree_.parse(*args, **kwargs)
+    return doc
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+
+#
+# Data representation classes
+#
+
+
+class containerTypeSub(supermod.containerType):
+    def __init__(self, sample1=None, sample2_bad=None, sample3_bad=None, sample2=None):
+        super(containerTypeSub, self).__init__(sample1, sample2_bad, sample3_bad, sample2, )
+supermod.containerType.subclass = containerTypeSub
+# end class containerTypeSub
+
+
+class simpleOneTypeSub(supermod.simpleOneType):
+    def __init__(self, token_enum_value=None, integer_range_incl_value=None, integer_range_excl_value=None, min_max_length_value=None, length_value=None, totaldigits_value=None, anonymous_float_value=None):
+        super(simpleOneTypeSub, self).__init__(token_enum_value, integer_range_incl_value, integer_range_excl_value, min_max_length_value, length_value, totaldigits_value, anonymous_float_value, )
+supermod.simpleOneType.subclass = simpleOneTypeSub
+# end class simpleOneTypeSub
+
+
+class simpleTwoTypeSub(supermod.simpleTwoType):
+    def __init__(self, Foo=None):
+        super(simpleTwoTypeSub, self).__init__(Foo, )
+supermod.simpleTwoType.subclass = simpleTwoTypeSub
+# end class simpleTwoTypeSub
+
+
+class FooType1Sub(supermod.FooType1):
+    def __init__(self, FooType=None):
+        super(FooType1Sub, self).__init__(FooType, )
+supermod.FooType1.subclass = FooType1Sub
+# end class FooType1Sub
+
+
+def get_root_tag(node):
+    tag = supermod.Tag_pattern_.match(node.tag).groups()[-1]
+    rootClass = None
+    rootClass = supermod.GDSClassesMapping.get(tag)
+    if rootClass is None and hasattr(supermod, tag):
+        rootClass = getattr(supermod, tag)
+    return tag, rootClass
+
+
+def parse(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='',
+            pretty_print=True)
+    return rootObj
+
+
+def parseEtree(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    mapping = {}
+    rootElement = rootObj.to_etree(None, name_=rootTag, mapping_=mapping)
+    reverse_mapping = rootObj.gds_reverse_node_mapping(mapping)
+    if not silence:
+        content = etree_.tostring(
+            rootElement, pretty_print=True,
+            xml_declaration=True, encoding="utf-8")
+        sys.stdout.write(content)
+        sys.stdout.write('\n')
+    return rootObj, rootElement, mapping, reverse_mapping
+
+
+def parseString(inString, silence=False):
+    from StringIO import StringIO
+    doc = parsexml_(StringIO(inString))
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='')
+    return rootObj
+
+
+def parseLiteral(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('#from validate_simpletypes2_sup import *\n\n')
+        sys.stdout.write('import validate_simpletypes2_sup as model_\n\n')
+        sys.stdout.write('rootObj = model_.rootClass(\n')
+        rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
+        sys.stdout.write(')\n')
+    return rootObj
+
+
+USAGE_TEXT = """
+Usage: python ???.py <infilename>
+"""
+
+
+def usage():
+    print USAGE_TEXT
+    sys.exit(1)
+
+
+def main():
+    args = sys.argv[1:]
+    if len(args) != 1:
+        usage()
+    infilename = args[0]
+    parse(infilename)
+
+
+if __name__ == '__main__':
+    #import pdb; pdb.set_trace()
+    main()
diff --git a/tests/validate_simpletypes1_sup.py b/tests/validate_simpletypes1_sup.py
new file mode 100644
index 0000000..77d9886
--- /dev/null
+++ b/tests/validate_simpletypes1_sup.py
@@ -0,0 +1,1396 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Generated  by generateDS.py.
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-o', 'tests/validate_simpletypes2_sup.py')
+#   ('-s', 'tests/validate_simpletypes2_sub.py')
+#   ('--super', 'validate_simpletypes2_sup')
+#
+# Command line arguments:
+#   tests/validate_simpletypes.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --member-specs="list" -f -o "tests/validate_simpletypes2_sup.py" -s "tests/validate_simpletypes2_sub.py" --super="validate_simpletypes2_sup" tests/validate_simpletypes.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+import getopt
+import re as re_
+import base64
+import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
+
+etree_ = None
+Verbose_import_ = False
+(
+    XMLParser_import_none, XMLParser_import_lxml,
+    XMLParser_import_elementtree
+) = range(3)
+XMLParser_import_library = None
+try:
+    # lxml
+    from lxml import etree as etree_
+    XMLParser_import_library = XMLParser_import_lxml
+    if Verbose_import_:
+        print("running with lxml.etree")
+except ImportError:
+    try:
+        # cElementTree from Python 2.5+
+        import xml.etree.cElementTree as etree_
+        XMLParser_import_library = XMLParser_import_elementtree
+        if Verbose_import_:
+            print("running with cElementTree on Python 2.5+")
+    except ImportError:
+        try:
+            # ElementTree from Python 2.5+
+            import xml.etree.ElementTree as etree_
+            XMLParser_import_library = XMLParser_import_elementtree
+            if Verbose_import_:
+                print("running with ElementTree on Python 2.5+")
+        except ImportError:
+            try:
+                # normal cElementTree install
+                import cElementTree as etree_
+                XMLParser_import_library = XMLParser_import_elementtree
+                if Verbose_import_:
+                    print("running with cElementTree")
+            except ImportError:
+                try:
+                    # normal ElementTree install
+                    import elementtree.ElementTree as etree_
+                    XMLParser_import_library = XMLParser_import_elementtree
+                    if Verbose_import_:
+                        print("running with ElementTree")
+                except ImportError:
+                    raise ImportError(
+                        "Failed to import ElementTree from any known place")
+
+
+def parsexml_(*args, **kwargs):
+    if (XMLParser_import_library == XMLParser_import_lxml and
+            'parser' not in kwargs):
+        # Use the lxml ElementTree compatible parser so that, e.g.,
+        #   we ignore comments.
+        kwargs['parser'] = etree_.ETCompatXMLParser()
+    doc = etree_.parse(*args, **kwargs)
+    return doc
+
+#
+# User methods
+#
+# Calls to the methods in these classes are generated by generateDS.py.
+# You can replace these methods by re-implementing the following class
+#   in a module named generatedssuper.py.
+
+try:
+    from generatedssuper import GeneratedsSuper
+except ImportError, exp:
+
+    class GeneratedsSuper(object):
+        tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
+        class _FixedOffsetTZ(datetime_.tzinfo):
+            def __init__(self, offset, name):
+                self.__offset = datetime_.timedelta(minutes=offset)
+                self.__name = name
+            def utcoffset(self, dt):
+                return self.__offset
+            def tzname(self, dt):
+                return self.__name
+            def dst(self, dt):
+                return None
+        def gds_format_string(self, input_data, input_name=''):
+            return input_data
+        def gds_validate_string(self, input_data, node, input_name=''):
+            if not input_data:
+                return ''
+            else:
+                return input_data
+        def gds_format_base64(self, input_data, input_name=''):
+            return base64.b64encode(input_data)
+        def gds_validate_base64(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_integer(self, input_data, input_name=''):
+            return '%d' % input_data
+        def gds_validate_integer(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_integer_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_integer_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of integers')
+            return values
+        def gds_format_float(self, input_data, input_name=''):
+            return ('%.15f' % input_data).rstrip('0')
+        def gds_validate_float(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_float_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_float_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of floats')
+            return values
+        def gds_format_double(self, input_data, input_name=''):
+            return '%e' % input_data
+        def gds_validate_double(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_double_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_double_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of doubles')
+            return values
+        def gds_format_boolean(self, input_data, input_name=''):
+            return ('%s' % input_data).lower()
+        def gds_validate_boolean(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_boolean_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_boolean_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                if value not in ('true', '1', 'false', '0', ):
+                    raise_parse_error(
+                        node,
+                        'Requires sequence of booleans '
+                        '("true", "1", "false", "0")')
+            return values
+        def gds_validate_datetime(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_datetime(self, input_data, input_name=''):
+            if input_data.microsecond == 0:
+                _svalue = '%04d-%02d-%02dT%02d:%02d:%02d' % (
+                    input_data.year,
+                    input_data.month,
+                    input_data.day,
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                )
+            else:
+                _svalue = '%04d-%02d-%02dT%02d:%02d:%02d.%s' % (
+                    input_data.year,
+                    input_data.month,
+                    input_data.day,
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                    ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+                )
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            return _svalue
+        @classmethod
+        def gds_parse_datetime(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            time_parts = input_data.split('.')
+            if len(time_parts) > 1:
+                micro_seconds = int(float('0.' + time_parts[1]) * 1000000)
+                input_data = '%s.%s' % (time_parts[0], micro_seconds, )
+                dt = datetime_.datetime.strptime(
+                    input_data, '%Y-%m-%dT%H:%M:%S.%f')
+            else:
+                dt = datetime_.datetime.strptime(
+                    input_data, '%Y-%m-%dT%H:%M:%S')
+            dt = dt.replace(tzinfo=tz)
+            return dt
+        def gds_validate_date(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_date(self, input_data, input_name=''):
+            _svalue = '%04d-%02d-%02d' % (
+                input_data.year,
+                input_data.month,
+                input_data.day,
+            )
+            try:
+                if input_data.tzinfo is not None:
+                    tzoff = input_data.tzinfo.utcoffset(input_data)
+                    if tzoff is not None:
+                        total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                        if total_seconds == 0:
+                            _svalue += 'Z'
+                        else:
+                            if total_seconds < 0:
+                                _svalue += '-'
+                                total_seconds *= -1
+                            else:
+                                _svalue += '+'
+                            hours = total_seconds // 3600
+                            minutes = (total_seconds - (hours * 3600)) // 60
+                            _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            except AttributeError:
+                pass
+            return _svalue
+        @classmethod
+        def gds_parse_date(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            dt = datetime_.datetime.strptime(input_data, '%Y-%m-%d')
+            dt = dt.replace(tzinfo=tz)
+            return dt.date()
+        def gds_validate_time(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_time(self, input_data, input_name=''):
+            if input_data.microsecond == 0:
+                _svalue = '%02d:%02d:%02d' % (
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                )
+            else:
+                _svalue = '%02d:%02d:%02d.%s' % (
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                    ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+                )
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            return _svalue
+        @classmethod
+        def gds_parse_time(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            if len(input_data.split('.')) > 1:
+                dt = datetime_.datetime.strptime(input_data, '%H:%M:%S.%f')
+            else:
+                dt = datetime_.datetime.strptime(input_data, '%H:%M:%S')
+            dt = dt.replace(tzinfo=tz)
+            return dt.time()
+        def gds_str_lower(self, instring):
+            return instring.lower()
+        def get_path_(self, node):
+            path_list = []
+            self.get_path_list_(node, path_list)
+            path_list.reverse()
+            path = '/'.join(path_list)
+            return path
+        Tag_strip_pattern_ = re_.compile(r'\{.*\}')
+        def get_path_list_(self, node, path_list):
+            if node is None:
+                return
+            tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag)
+            if tag:
+                path_list.append(tag)
+            self.get_path_list_(node.getparent(), path_list)
+        def get_class_obj_(self, node, default_class=None):
+            class_obj1 = default_class
+            if 'xsi' in node.nsmap:
+                classname = node.get('{%s}type' % node.nsmap['xsi'])
+                if classname is not None:
+                    names = classname.split(':')
+                    if len(names) == 2:
+                        classname = names[1]
+                    class_obj2 = globals().get(classname)
+                    if class_obj2 is not None:
+                        class_obj1 = class_obj2
+            return class_obj1
+        def gds_build_any(self, node, type_name=None):
+            return None
+        @classmethod
+        def gds_reverse_node_mapping(cls, mapping):
+            return dict(((v, k) for k, v in mapping.iteritems()))
+
+
+#
+# If you have installed IPython you can uncomment and use the following.
+# IPython is available from http://ipython.scipy.org/.
+#
+
+## from IPython.Shell import IPShellEmbed
+## args = ''
+## ipshell = IPShellEmbed(args,
+##     banner = 'Dropping into IPython',
+##     exit_msg = 'Leaving Interpreter, back to program.')
+
+# Then use the following line where and when you want to drop into the
+# IPython shell:
+#    ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+Tag_pattern_ = re_.compile(r'({.*})?(.*)')
+String_cleanup_pat_ = re_.compile(r"[\n\r\s]+")
+Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)')
+
+#
+# Support/utility functions.
+#
+
+
+def showIndent(outfile, level, pretty_print=True):
+    if pretty_print:
+        for idx in range(level):
+            outfile.write('    ')
+
+
+def quote_xml(inStr):
+    if not inStr:
+        return ''
+    s1 = (isinstance(inStr, basestring) and inStr or
+          '%s' % inStr)
+    s1 = s1.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    return s1
+
+
+def quote_attrib(inStr):
+    s1 = (isinstance(inStr, basestring) and inStr or
+          '%s' % inStr)
+    s1 = s1.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    if '"' in s1:
+        if "'" in s1:
+            s1 = '"%s"' % s1.replace('"', "&quot;")
+        else:
+            s1 = "'%s'" % s1
+    else:
+        s1 = '"%s"' % s1
+    return s1
+
+
+def quote_python(inStr):
+    s1 = inStr
+    if s1.find("'") == -1:
+        if s1.find('\n') == -1:
+            return "'%s'" % s1
+        else:
+            return "'''%s'''" % s1
+    else:
+        if s1.find('"') != -1:
+            s1 = s1.replace('"', '\\"')
+        if s1.find('\n') == -1:
+            return '"%s"' % s1
+        else:
+            return '"""%s"""' % s1
+
+
+def get_all_text_(node):
+    if node.text is not None:
+        text = node.text
+    else:
+        text = ''
+    for child in node:
+        if child.tail is not None:
+            text += child.tail
+    return text
+
+
+def find_attr_value_(attr_name, node):
+    attrs = node.attrib
+    attr_parts = attr_name.split(':')
+    value = None
+    if len(attr_parts) == 1:
+        value = attrs.get(attr_name)
+    elif len(attr_parts) == 2:
+        prefix, name = attr_parts
+        namespace = node.nsmap.get(prefix)
+        if namespace is not None:
+            value = attrs.get('{%s}%s' % (namespace, name, ))
+    return value
+
+
+class GDSParseError(Exception):
+    pass
+
+
+def raise_parse_error(node, msg):
+    if XMLParser_import_library == XMLParser_import_lxml:
+        msg = '%s (element %s/line %d)' % (
+            msg, node.tag, node.sourceline, )
+    else:
+        msg = '%s (element %s)' % (msg, node.tag, )
+    raise GDSParseError(msg)
+
+
+class MixedContainer:
+    # Constants for category:
+    CategoryNone = 0
+    CategoryText = 1
+    CategorySimple = 2
+    CategoryComplex = 3
+    # Constants for content_type:
+    TypeNone = 0
+    TypeText = 1
+    TypeString = 2
+    TypeInteger = 3
+    TypeFloat = 4
+    TypeDecimal = 5
+    TypeDouble = 6
+    TypeBoolean = 7
+    TypeBase64 = 8
+    def __init__(self, category, content_type, name, value):
+        self.category = category
+        self.content_type = content_type
+        self.name = name
+        self.value = value
+    def getCategory(self):
+        return self.category
+    def getContenttype(self, content_type):
+        return self.content_type
+    def getValue(self):
+        return self.value
+    def getName(self):
+        return self.name
+    def export(self, outfile, level, name, namespace, pretty_print=True):
+        if self.category == MixedContainer.CategoryText:
+            # Prevent exporting empty content as empty lines.
+            if self.value.strip():
+                outfile.write(self.value)
+        elif self.category == MixedContainer.CategorySimple:
+            self.exportSimple(outfile, level, name)
+        else:    # category == MixedContainer.CategoryComplex
+            self.value.export(outfile, level, namespace, name, pretty_print)
+    def exportSimple(self, outfile, level, name):
+        if self.content_type == MixedContainer.TypeString:
+            outfile.write('<%s>%s</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeInteger or \
+                self.content_type == MixedContainer.TypeBoolean:
+            outfile.write('<%s>%d</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeFloat or \
+                self.content_type == MixedContainer.TypeDecimal:
+            outfile.write('<%s>%f</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeDouble:
+            outfile.write('<%s>%g</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeBase64:
+            outfile.write('<%s>%s</%s>' % (
+                self.name, base64.b64encode(self.value), self.name))
+    def to_etree(self, element):
+        if self.category == MixedContainer.CategoryText:
+            # Prevent exporting empty content as empty lines.
+            if self.value.strip():
+                if len(element) > 0:
+                    if element[-1].tail is None:
+                        element[-1].tail = self.value
+                    else:
+                        element[-1].tail += self.value
+                else:
+                    if element.text is None:
+                        element.text = self.value
+                    else:
+                        element.text += self.value
+        elif self.category == MixedContainer.CategorySimple:
+            subelement = etree_.SubElement(element, '%s' % self.name)
+            subelement.text = self.to_etree_simple()
+        else:    # category == MixedContainer.CategoryComplex
+            self.value.to_etree(element)
+    def to_etree_simple(self):
+        if self.content_type == MixedContainer.TypeString:
+            text = self.value
+        elif (self.content_type == MixedContainer.TypeInteger or
+                self.content_type == MixedContainer.TypeBoolean):
+            text = '%d' % self.value
+        elif (self.content_type == MixedContainer.TypeFloat or
+                self.content_type == MixedContainer.TypeDecimal):
+            text = '%f' % self.value
+        elif self.content_type == MixedContainer.TypeDouble:
+            text = '%g' % self.value
+        elif self.content_type == MixedContainer.TypeBase64:
+            text = '%s' % base64.b64encode(self.value)
+        return text
+    def exportLiteral(self, outfile, level, name):
+        if self.category == MixedContainer.CategoryText:
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+                    self.category, self.content_type, self.name, self.value))
+        elif self.category == MixedContainer.CategorySimple:
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+                    self.category, self.content_type, self.name, self.value))
+        else:    # category == MixedContainer.CategoryComplex
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s",\n' % (
+                    self.category, self.content_type, self.name,))
+            self.value.exportLiteral(outfile, level + 1)
+            showIndent(outfile, level)
+            outfile.write(')\n')
+
+
+class MemberSpec_(object):
+    def __init__(self, name='', data_type='', container=0):
+        self.name = name
+        self.data_type = data_type
+        self.container = container
+    def set_name(self, name): self.name = name
+    def get_name(self): return self.name
+    def set_data_type(self, data_type): self.data_type = data_type
+    def get_data_type_chain(self): return self.data_type
+    def get_data_type(self):
+        if isinstance(self.data_type, list):
+            if len(self.data_type) > 0:
+                return self.data_type[-1]
+            else:
+                return 'xs:string'
+        else:
+            return self.data_type
+    def set_container(self, container): self.container = container
+    def get_container(self): return self.container
+
+
+def _cast(typ, value):
+    if typ is None or value is None:
+        return value
+    return typ(value)
+
+#
+# Data representation classes.
+#
+
+
+class containerType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('sample1', 'simpleOneType', 1),
+        MemberSpec_('sample2_bad', 'simpleOneType', 1),
+        MemberSpec_('sample3_bad', 'simpleOneType', 1),
+        MemberSpec_('sample2', 'simpleTwoType', 1),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, sample1=None, sample2_bad=None, sample3_bad=None, sample2=None):
+        self.original_tagname_ = None
+        if sample1 is None:
+            self.sample1 = []
+        else:
+            self.sample1 = sample1
+        if sample2_bad is None:
+            self.sample2_bad = []
+        else:
+            self.sample2_bad = sample2_bad
+        if sample3_bad is None:
+            self.sample3_bad = []
+        else:
+            self.sample3_bad = sample3_bad
+        if sample2 is None:
+            self.sample2 = []
+        else:
+            self.sample2 = sample2
+    def factory(*args_, **kwargs_):
+        if containerType.subclass:
+            return containerType.subclass(*args_, **kwargs_)
+        else:
+            return containerType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_sample1(self): return self.sample1
+    def set_sample1(self, sample1): self.sample1 = sample1
+    def add_sample1(self, value): self.sample1.append(value)
+    def insert_sample1_at(self, index, value): self.sample1.insert(index, value)
+    def replace_sample1_at(self, index, value): self.sample1[index] = value
+    def get_sample2_bad(self): return self.sample2_bad
+    def set_sample2_bad(self, sample2_bad): self.sample2_bad = sample2_bad
+    def add_sample2_bad(self, value): self.sample2_bad.append(value)
+    def insert_sample2_bad_at(self, index, value): self.sample2_bad.insert(index, value)
+    def replace_sample2_bad_at(self, index, value): self.sample2_bad[index] = value
+    def get_sample3_bad(self): return self.sample3_bad
+    def set_sample3_bad(self, sample3_bad): self.sample3_bad = sample3_bad
+    def add_sample3_bad(self, value): self.sample3_bad.append(value)
+    def insert_sample3_bad_at(self, index, value): self.sample3_bad.insert(index, value)
+    def replace_sample3_bad_at(self, index, value): self.sample3_bad[index] = value
+    def get_sample2(self): return self.sample2
+    def set_sample2(self, sample2): self.sample2 = sample2
+    def add_sample2(self, value): self.sample2.append(value)
+    def insert_sample2_at(self, index, value): self.sample2.insert(index, value)
+    def replace_sample2_at(self, index, value): self.sample2[index] = value
+    def hasContent_(self):
+        if (
+            self.sample1 or
+            self.sample2_bad or
+            self.sample3_bad or
+            self.sample2
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='containerType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='containerType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='containerType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='containerType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='containerType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        for sample1_ in self.sample1:
+            sample1_.export(outfile, level, namespace_, name_='sample1', pretty_print=pretty_print)
+        for sample2_bad_ in self.sample2_bad:
+            sample2_bad_.export(outfile, level, namespace_, name_='sample2_bad', pretty_print=pretty_print)
+        for sample3_bad_ in self.sample3_bad:
+            sample3_bad_.export(outfile, level, namespace_, name_='sample3_bad', pretty_print=pretty_print)
+        for sample2_ in self.sample2:
+            sample2_.export(outfile, level, namespace_, name_='sample2', pretty_print=pretty_print)
+    def exportLiteral(self, outfile, level, name_='containerType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        showIndent(outfile, level)
+        outfile.write('sample1=[\n')
+        level += 1
+        for sample1_ in self.sample1:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample1_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample2_bad=[\n')
+        level += 1
+        for sample2_bad_ in self.sample2_bad:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample2_bad_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample3_bad=[\n')
+        level += 1
+        for sample3_bad_ in self.sample3_bad:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample3_bad_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample2=[\n')
+        level += 1
+        for sample2_ in self.sample2:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleTwoType(\n')
+            sample2_.exportLiteral(outfile, level, name_='simpleTwoType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'sample1':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample1.append(obj_)
+            obj_.original_tagname_ = 'sample1'
+        elif nodeName_ == 'sample2_bad':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample2_bad.append(obj_)
+            obj_.original_tagname_ = 'sample2_bad'
+        elif nodeName_ == 'sample3_bad':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample3_bad.append(obj_)
+            obj_.original_tagname_ = 'sample3_bad'
+        elif nodeName_ == 'sample2':
+            obj_ = simpleTwoType.factory()
+            obj_.build(child_)
+            self.sample2.append(obj_)
+            obj_.original_tagname_ = 'sample2'
+# end class containerType
+
+
+class simpleOneType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('token_enum_value', ['token_enum_st', 'xs:NMTOKEN'], 0),
+        MemberSpec_('token_enum_value', ['token_enum_st', 'xs:NMTOKEN'], 0),
+        MemberSpec_('integer_range_incl_value', ['integer_range_incl_st', 'xs:integer'], 0),
+        MemberSpec_('integer_range_excl_value', ['integer_range_excl_st', 'xs:integer'], 0),
+        MemberSpec_('min_max_length_value', ['min_max_length_st', 'xs:string'], 0),
+        MemberSpec_('length_value', ['length_st', 'xs:string'], 0),
+        MemberSpec_('totaldigits_value', ['totaldigits_st', 'xs:float'], 0),
+        MemberSpec_('anonymous_float_value', ['anonymous_float_valueType', 'xs:float'], 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, token_enum_value=None, integer_range_incl_value=None, integer_range_excl_value=None, min_max_length_value=None, length_value=None, totaldigits_value=None, anonymous_float_value=None):
+        self.original_tagname_ = None
+        self.token_enum_value = token_enum_value
+        self.validate_token_enum_st(self.token_enum_value)
+        self.token_enum_value = token_enum_value
+        self.validate_token_enum_st(self.token_enum_value)
+        self.integer_range_incl_value = integer_range_incl_value
+        self.validate_integer_range_incl_st(self.integer_range_incl_value)
+        self.integer_range_excl_value = integer_range_excl_value
+        self.validate_integer_range_excl_st(self.integer_range_excl_value)
+        self.min_max_length_value = min_max_length_value
+        self.validate_min_max_length_st(self.min_max_length_value)
+        self.length_value = length_value
+        self.validate_length_st(self.length_value)
+        self.totaldigits_value = totaldigits_value
+        self.validate_totaldigits_st(self.totaldigits_value)
+        self.anonymous_float_value = anonymous_float_value
+        self.validate_anonymous_float_valueType(self.anonymous_float_value)
+    def factory(*args_, **kwargs_):
+        if simpleOneType.subclass:
+            return simpleOneType.subclass(*args_, **kwargs_)
+        else:
+            return simpleOneType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_token_enum_value(self): return self.token_enum_value
+    def set_token_enum_value(self, token_enum_value): self.token_enum_value = token_enum_value
+    def get_token_enum_value(self): return self.token_enum_value
+    def set_token_enum_value(self, token_enum_value): self.token_enum_value = token_enum_value
+    def get_integer_range_incl_value(self): return self.integer_range_incl_value
+    def set_integer_range_incl_value(self, integer_range_incl_value): self.integer_range_incl_value = integer_range_incl_value
+    def get_integer_range_excl_value(self): return self.integer_range_excl_value
+    def set_integer_range_excl_value(self, integer_range_excl_value): self.integer_range_excl_value = integer_range_excl_value
+    def get_min_max_length_value(self): return self.min_max_length_value
+    def set_min_max_length_value(self, min_max_length_value): self.min_max_length_value = min_max_length_value
+    def get_length_value(self): return self.length_value
+    def set_length_value(self, length_value): self.length_value = length_value
+    def get_totaldigits_value(self): return self.totaldigits_value
+    def set_totaldigits_value(self, totaldigits_value): self.totaldigits_value = totaldigits_value
+    def get_anonymous_float_value(self): return self.anonymous_float_value
+    def set_anonymous_float_value(self, anonymous_float_value): self.anonymous_float_value = anonymous_float_value
+    def validate_token_enum_st(self, value):
+        # Validate type token_enum_st, a restriction on xs:NMTOKEN.
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on token_enum_st' % {"value" : value.encode("utf-8")} )
+    def validate_integer_range_incl_st(self, value):
+        # Validate type integer_range_incl_st, a restriction on xs:integer.
+        if value is not None and Validate_simpletypes_:
+           if value <= -5:
+               warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on integer_range_incl_st' % {"value" : value} )
+           if value >= 10:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on integer_range_incl_st' % {"value" : value} )
+    def validate_integer_range_excl_st(self, value):
+        # Validate type integer_range_excl_st, a restriction on xs:integer.
+        if value is not None and Validate_simpletypes_:
+           if value < -5:
+               warnings.warn('Value "%(value)s" does not match xsd minExclusive restriction on integer_range_excl_st' % {"value" : value} )
+           if value > 10:
+               warnings.warn('Value "%(value)s" does not match xsd maxExclusive restriction on integer_range_excl_st' % {"value" : value} )
+    def validate_min_max_length_st(self, value):
+        # Validate type min_max_length_st, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 10:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+           if len(value) > 20:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+    def validate_length_st(self, value):
+        # Validate type length_st, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) != 10:
+               warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+    def validate_totaldigits_st(self, value):
+        # Validate type totaldigits_st, a restriction on xs:float.
+        if value is not None and Validate_simpletypes_:
+           if len(str(value)) >= 15:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on totaldigits_st' % {"value" : value} )
+    def validate_anonymous_float_valueType(self, value):
+        # Validate type anonymous_float_valueType, a restriction on xs:float.
+        if value is not None and Validate_simpletypes_:
+           if value <= 1.1:
+               warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+           if value >= 4.4:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+    def hasContent_(self):
+        if (
+            self.token_enum_value is not None or
+            self.token_enum_value is not None or
+            self.integer_range_incl_value is not None or
+            self.integer_range_excl_value is not None or
+            self.min_max_length_value is not None or
+            self.length_value is not None or
+            self.totaldigits_value is not None or
+            self.anonymous_float_value is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='simpleOneType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='simpleOneType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='simpleOneType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='simpleOneType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='simpleOneType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.token_enum_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stoken_enum_value>%s</%stoken_enum_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.token_enum_value).encode(ExternalEncoding), input_name='token_enum_value'), namespace_, eol_))
+        if self.token_enum_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stoken_enum_value>%s</%stoken_enum_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.token_enum_value).encode(ExternalEncoding), input_name='token_enum_value'), namespace_, eol_))
+        if self.integer_range_incl_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sinteger_range_incl_value>%s</%sinteger_range_incl_value>%s' % (namespace_, self.gds_format_integer(self.integer_range_incl_value, input_name='integer_range_incl_value'), namespace_, eol_))
+        if self.integer_range_excl_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sinteger_range_excl_value>%s</%sinteger_range_excl_value>%s' % (namespace_, self.gds_format_integer(self.integer_range_excl_value, input_name='integer_range_excl_value'), namespace_, eol_))
+        if self.min_max_length_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%smin_max_length_value>%s</%smin_max_length_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.min_max_length_value).encode(ExternalEncoding), input_name='min_max_length_value'), namespace_, eol_))
+        if self.length_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%slength_value>%s</%slength_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.length_value).encode(ExternalEncoding), input_name='length_value'), namespace_, eol_))
+        if self.totaldigits_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stotaldigits_value>%s</%stotaldigits_value>%s' % (namespace_, self.gds_format_float(self.totaldigits_value, input_name='totaldigits_value'), namespace_, eol_))
+        if self.anonymous_float_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sanonymous_float_value>%s</%sanonymous_float_value>%s' % (namespace_, self.gds_format_float(self.anonymous_float_value, input_name='anonymous_float_value'), namespace_, eol_))
+    def exportLiteral(self, outfile, level, name_='simpleOneType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.token_enum_value is not None:
+            showIndent(outfile, level)
+            outfile.write('token_enum_value=%s,\n' % quote_python(self.token_enum_value).encode(ExternalEncoding))
+        if self.token_enum_value is not None:
+            showIndent(outfile, level)
+            outfile.write('token_enum_value=%s,\n' % quote_python(self.token_enum_value).encode(ExternalEncoding))
+        if self.integer_range_incl_value is not None:
+            showIndent(outfile, level)
+            outfile.write('integer_range_incl_value=%d,\n' % self.integer_range_incl_value)
+        if self.integer_range_excl_value is not None:
+            showIndent(outfile, level)
+            outfile.write('integer_range_excl_value=%d,\n' % self.integer_range_excl_value)
+        if self.min_max_length_value is not None:
+            showIndent(outfile, level)
+            outfile.write('min_max_length_value=%s,\n' % quote_python(self.min_max_length_value).encode(ExternalEncoding))
+        if self.length_value is not None:
+            showIndent(outfile, level)
+            outfile.write('length_value=%s,\n' % quote_python(self.length_value).encode(ExternalEncoding))
+        if self.totaldigits_value is not None:
+            showIndent(outfile, level)
+            outfile.write('totaldigits_value=%f,\n' % self.totaldigits_value)
+        if self.anonymous_float_value is not None:
+            showIndent(outfile, level)
+            outfile.write('anonymous_float_value=%f,\n' % self.anonymous_float_value)
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'token_enum_value':
+            token_enum_value_ = child_.text
+            token_enum_value_ = self.gds_validate_string(token_enum_value_, node, 'token_enum_value')
+            self.token_enum_value = token_enum_value_
+            self.validate_token_enum_st(self.token_enum_value)    # validate type token_enum_st
+        elif nodeName_ == 'token_enum_value':
+            token_enum_value_ = child_.text
+            token_enum_value_ = self.gds_validate_string(token_enum_value_, node, 'token_enum_value')
+            self.token_enum_value = token_enum_value_
+            self.validate_token_enum_st(self.token_enum_value)    # validate type token_enum_st
+        elif nodeName_ == 'integer_range_incl_value':
+            sval_ = child_.text
+            try:
+                ival_ = int(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires integer: %s' % exp)
+            ival_ = self.gds_validate_integer(ival_, node, 'integer_range_incl_value')
+            self.integer_range_incl_value = ival_
+            self.validate_integer_range_incl_st(self.integer_range_incl_value)    # validate type integer_range_incl_st
+        elif nodeName_ == 'integer_range_excl_value':
+            sval_ = child_.text
+            try:
+                ival_ = int(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires integer: %s' % exp)
+            ival_ = self.gds_validate_integer(ival_, node, 'integer_range_excl_value')
+            self.integer_range_excl_value = ival_
+            self.validate_integer_range_excl_st(self.integer_range_excl_value)    # validate type integer_range_excl_st
+        elif nodeName_ == 'min_max_length_value':
+            min_max_length_value_ = child_.text
+            min_max_length_value_ = self.gds_validate_string(min_max_length_value_, node, 'min_max_length_value')
+            self.min_max_length_value = min_max_length_value_
+            self.validate_min_max_length_st(self.min_max_length_value)    # validate type min_max_length_st
+        elif nodeName_ == 'length_value':
+            length_value_ = child_.text
+            length_value_ = self.gds_validate_string(length_value_, node, 'length_value')
+            self.length_value = length_value_
+            self.validate_length_st(self.length_value)    # validate type length_st
+        elif nodeName_ == 'totaldigits_value':
+            sval_ = child_.text
+            try:
+                fval_ = float(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires float or double: %s' % exp)
+            fval_ = self.gds_validate_float(fval_, node, 'totaldigits_value')
+            self.totaldigits_value = fval_
+            self.validate_totaldigits_st(self.totaldigits_value)    # validate type totaldigits_st
+        elif nodeName_ == 'anonymous_float_value':
+            sval_ = child_.text
+            try:
+                fval_ = float(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires float or double: %s' % exp)
+            fval_ = self.gds_validate_float(fval_, node, 'anonymous_float_value')
+            self.anonymous_float_value = fval_
+            self.validate_anonymous_float_valueType(self.anonymous_float_value)    # validate type anonymous_float_valueType
+# end class simpleOneType
+
+
+class simpleTwoType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('Foo', 'FooType1', 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, Foo=None):
+        self.original_tagname_ = None
+        self.Foo = Foo
+    def factory(*args_, **kwargs_):
+        if simpleTwoType.subclass:
+            return simpleTwoType.subclass(*args_, **kwargs_)
+        else:
+            return simpleTwoType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_Foo(self): return self.Foo
+    def set_Foo(self, Foo): self.Foo = Foo
+    def hasContent_(self):
+        if (
+            self.Foo is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='simpleTwoType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='simpleTwoType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='simpleTwoType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='simpleTwoType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='simpleTwoType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.Foo is not None:
+            self.Foo.export(outfile, level, namespace_, name_='Foo', pretty_print=pretty_print)
+    def exportLiteral(self, outfile, level, name_='simpleTwoType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.Foo is not None:
+            showIndent(outfile, level)
+            outfile.write('Foo=model_.FooType1(\n')
+            self.Foo.exportLiteral(outfile, level, name_='Foo')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'Foo':
+            obj_ = FooType1.factory()
+            obj_.build(child_)
+            self.Foo = obj_
+            obj_.original_tagname_ = 'Foo'
+# end class simpleTwoType
+
+
+class FooType1(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('FooType', ['FooTypeType', 'xs:string'], 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, FooType=None):
+        self.original_tagname_ = None
+        self.FooType = FooType
+        self.validate_FooTypeType(self.FooType)
+    def factory(*args_, **kwargs_):
+        if FooType1.subclass:
+            return FooType1.subclass(*args_, **kwargs_)
+        else:
+            return FooType1(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_FooType(self): return self.FooType
+    def set_FooType(self, FooType): self.FooType = FooType
+    def validate_FooTypeType(self, value):
+        # Validate type FooTypeType, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 12:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 24:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+    def hasContent_(self):
+        if (
+            self.FooType is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='FooType1', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='FooType1')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='FooType1', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='FooType1'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='FooType1', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.FooType is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sFooType>%s</%sFooType>%s' % (namespace_, self.gds_format_string(quote_xml(self.FooType).encode(ExternalEncoding), input_name='FooType'), namespace_, eol_))
+    def exportLiteral(self, outfile, level, name_='FooType1'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.FooType is not None:
+            showIndent(outfile, level)
+            outfile.write('FooType=%s,\n' % quote_python(self.FooType).encode(ExternalEncoding))
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'FooType':
+            FooType_ = child_.text
+            FooType_ = self.gds_validate_string(FooType_, node, 'FooType')
+            self.FooType = FooType_
+            self.validate_FooTypeType(self.FooType)    # validate type FooTypeType
+# end class FooType1
+
+
+GDSClassesMapping = {
+    'container': containerType,
+    'sample2_bad': simpleOneType,
+    'sample1': simpleOneType,
+    'sample3_bad': simpleOneType,
+    'sample2': simpleTwoType,
+    'Foo': FooType1,
+}
+
+
+USAGE_TEXT = """
+Usage: python <Parser>.py [ -s ] <in_xml_file>
+"""
+
+
+def usage():
+    print USAGE_TEXT
+    sys.exit(1)
+
+
+def get_root_tag(node):
+    tag = Tag_pattern_.match(node.tag).groups()[-1]
+    rootClass = GDSClassesMapping.get(tag)
+    if rootClass is None:
+        rootClass = globals().get(tag)
+    return tag, rootClass
+
+
+def parse(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='',
+            pretty_print=True)
+    return rootObj
+
+
+def parseEtree(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    mapping = {}
+    rootElement = rootObj.to_etree(None, name_=rootTag, mapping_=mapping)
+    reverse_mapping = rootObj.gds_reverse_node_mapping(mapping)
+    if not silence:
+        content = etree_.tostring(
+            rootElement, pretty_print=True,
+            xml_declaration=True, encoding="utf-8")
+        sys.stdout.write(content)
+        sys.stdout.write('\n')
+    return rootObj, rootElement, mapping, reverse_mapping
+
+
+def parseString(inString, silence=False):
+    from StringIO import StringIO
+    doc = parsexml_(StringIO(inString))
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='')
+    return rootObj
+
+
+def parseLiteral(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('#from validate_simpletypes2_sup import *\n\n')
+        sys.stdout.write('import validate_simpletypes2_sup as model_\n\n')
+        sys.stdout.write('rootObj = model_.rootClass(\n')
+        rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
+        sys.stdout.write(')\n')
+    return rootObj
+
+
+def main():
+    args = sys.argv[1:]
+    if len(args) == 1:
+        parse(args[0])
+    else:
+        usage()
+
+
+if __name__ == '__main__':
+    #import pdb; pdb.set_trace()
+    main()
+
+
+__all__ = [
+    "FooType1",
+    "containerType",
+    "simpleOneType",
+    "simpleTwoType"
+]
diff --git a/tests/validate_simpletypes1_warnings.txt b/tests/validate_simpletypes1_warnings.txt
new file mode 100644
index 0000000..39f7751
--- /dev/null
+++ b/tests/validate_simpletypes1_warnings.txt
@@ -0,0 +1,20 @@
+tests/validate_simpletypes2_sup.py:889: UserWarning: Value "floatxx" does not match xsd enumeration restriction on token_enum_st
+  warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on token_enum_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:896: UserWarning: Value "22" does not match xsd maxInclusive restriction on integer_range_incl_st
+  warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on integer_range_incl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:901: UserWarning: Value "-40" does not match xsd minExclusive restriction on integer_range_excl_st
+  warnings.warn('Value "%(value)s" does not match xsd minExclusive restriction on integer_range_excl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:908: UserWarning: Value "mno pqr" does not match xsd minLength restriction on min_max_length_st
+  warnings.warn('Value "%(value)s" does not match xsd minLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:915: UserWarning: Value "012345" does not match xsd length restriction on length_st
+  warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:925: UserWarning: Value "0.2" does not match xsd minInclusive restriction on anonymous_float_valueType
+  warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:894: UserWarning: Value "-50" does not match xsd minInclusive restriction on integer_range_incl_st
+  warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on integer_range_incl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:910: UserWarning: Value "asdf asdf asdf adf asdf asdf" does not match xsd maxLength restriction on min_max_length_st
+  warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:915: UserWarning: Value "01234567890" does not match xsd length restriction on length_st
+  warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:927: UserWarning: Value "6.6" does not match xsd maxInclusive restriction on anonymous_float_valueType
+  warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on anonymous_float_valueType' % {"value" : value} )
diff --git a/tests/validate_simpletypes2_out.xml b/tests/validate_simpletypes2_out.xml
new file mode 100644
index 0000000..70c8feb
--- /dev/null
+++ b/tests/validate_simpletypes2_out.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<container>
+    <sample1>
+        <token_enum_value>float</token_enum_value>
+        <token_enum_value>float</token_enum_value>
+        <integer_range_incl_value>2</integer_range_incl_value>
+        <integer_range_excl_value>7</integer_range_excl_value>
+        <min_max_length_value>abc def ghi</min_max_length_value>
+        <length_value>0123456789</length_value>
+        <totaldigits_value>12.456</totaldigits_value>
+        <anonymous_float_value>2.2</anonymous_float_value>
+    </sample1>
+    <sample2_bad>
+        <token_enum_value>floatxx</token_enum_value>
+        <token_enum_value>floatxx</token_enum_value>
+        <integer_range_incl_value>22</integer_range_incl_value>
+        <integer_range_excl_value>-40</integer_range_excl_value>
+        <min_max_length_value>mno pqr</min_max_length_value>
+        <length_value>012345</length_value>
+        <totaldigits_value>12.456789000000001</totaldigits_value>
+        <anonymous_float_value>0.2</anonymous_float_value>
+    </sample2_bad>
+    <sample3_bad>
+        <integer_range_incl_value>-50</integer_range_incl_value>
+        <min_max_length_value>asdf asdf asdf adf asdf asdf</min_max_length_value>
+        <length_value>01234567890</length_value>
+        <totaldigits_value>12345678.456789009273052</totaldigits_value>
+        <anonymous_float_value>6.6</anonymous_float_value>
+    </sample3_bad>
+</container>
diff --git a/tests/validate_simpletypes2_sub.py b/tests/validate_simpletypes2_sub.py
new file mode 100644
index 0000000..6b50bce
--- /dev/null
+++ b/tests/validate_simpletypes2_sub.py
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+
+#
+# Generated  by generateDS.py.
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-o', 'tests/validate_simpletypes2_sup.py')
+#   ('-s', 'tests/validate_simpletypes2_sub.py')
+#   ('--super', 'validate_simpletypes2_sup')
+#
+# Command line arguments:
+#   tests/validate_simpletypes.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --member-specs="list" -f -o "tests/validate_simpletypes2_sup.py" -s "tests/validate_simpletypes2_sub.py" --super="validate_simpletypes2_sup" tests/validate_simpletypes.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+
+import validate_simpletypes2_sup as supermod
+
+etree_ = None
+Verbose_import_ = False
+(
+    XMLParser_import_none, XMLParser_import_lxml,
+    XMLParser_import_elementtree
+) = range(3)
+XMLParser_import_library = None
+try:
+    # lxml
+    from lxml import etree as etree_
+    XMLParser_import_library = XMLParser_import_lxml
+    if Verbose_import_:
+        print("running with lxml.etree")
+except ImportError:
+    try:
+        # cElementTree from Python 2.5+
+        import xml.etree.cElementTree as etree_
+        XMLParser_import_library = XMLParser_import_elementtree
+        if Verbose_import_:
+            print("running with cElementTree on Python 2.5+")
+    except ImportError:
+        try:
+            # ElementTree from Python 2.5+
+            import xml.etree.ElementTree as etree_
+            XMLParser_import_library = XMLParser_import_elementtree
+            if Verbose_import_:
+                print("running with ElementTree on Python 2.5+")
+        except ImportError:
+            try:
+                # normal cElementTree install
+                import cElementTree as etree_
+                XMLParser_import_library = XMLParser_import_elementtree
+                if Verbose_import_:
+                    print("running with cElementTree")
+            except ImportError:
+                try:
+                    # normal ElementTree install
+                    import elementtree.ElementTree as etree_
+                    XMLParser_import_library = XMLParser_import_elementtree
+                    if Verbose_import_:
+                        print("running with ElementTree")
+                except ImportError:
+                    raise ImportError(
+                        "Failed to import ElementTree from any known place")
+
+
+def parsexml_(*args, **kwargs):
+    if (XMLParser_import_library == XMLParser_import_lxml and
+            'parser' not in kwargs):
+        # Use the lxml ElementTree compatible parser so that, e.g.,
+        #   we ignore comments.
+        kwargs['parser'] = etree_.ETCompatXMLParser()
+    doc = etree_.parse(*args, **kwargs)
+    return doc
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+
+#
+# Data representation classes
+#
+
+
+class containerTypeSub(supermod.containerType):
+    def __init__(self, sample1=None, sample2_bad=None, sample3_bad=None, sample2=None):
+        super(containerTypeSub, self).__init__(sample1, sample2_bad, sample3_bad, sample2, )
+supermod.containerType.subclass = containerTypeSub
+# end class containerTypeSub
+
+
+class simpleOneTypeSub(supermod.simpleOneType):
+    def __init__(self, token_enum_value=None, integer_range_incl_value=None, integer_range_excl_value=None, min_max_length_value=None, length_value=None, totaldigits_value=None, anonymous_float_value=None):
+        super(simpleOneTypeSub, self).__init__(token_enum_value, integer_range_incl_value, integer_range_excl_value, min_max_length_value, length_value, totaldigits_value, anonymous_float_value, )
+supermod.simpleOneType.subclass = simpleOneTypeSub
+# end class simpleOneTypeSub
+
+
+class simpleTwoTypeSub(supermod.simpleTwoType):
+    def __init__(self, Foo=None):
+        super(simpleTwoTypeSub, self).__init__(Foo, )
+supermod.simpleTwoType.subclass = simpleTwoTypeSub
+# end class simpleTwoTypeSub
+
+
+class FooType1Sub(supermod.FooType1):
+    def __init__(self, FooType=None):
+        super(FooType1Sub, self).__init__(FooType, )
+supermod.FooType1.subclass = FooType1Sub
+# end class FooType1Sub
+
+
+def get_root_tag(node):
+    tag = supermod.Tag_pattern_.match(node.tag).groups()[-1]
+    rootClass = None
+    rootClass = supermod.GDSClassesMapping.get(tag)
+    if rootClass is None and hasattr(supermod, tag):
+        rootClass = getattr(supermod, tag)
+    return tag, rootClass
+
+
+def parse(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='',
+            pretty_print=True)
+    return rootObj
+
+
+def parseEtree(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    mapping = {}
+    rootElement = rootObj.to_etree(None, name_=rootTag, mapping_=mapping)
+    reverse_mapping = rootObj.gds_reverse_node_mapping(mapping)
+    if not silence:
+        content = etree_.tostring(
+            rootElement, pretty_print=True,
+            xml_declaration=True, encoding="utf-8")
+        sys.stdout.write(content)
+        sys.stdout.write('\n')
+    return rootObj, rootElement, mapping, reverse_mapping
+
+
+def parseString(inString, silence=False):
+    from StringIO import StringIO
+    doc = parsexml_(StringIO(inString))
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='')
+    return rootObj
+
+
+def parseLiteral(inFilename, silence=False):
+    doc = parsexml_(inFilename)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = supermod.containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('#from validate_simpletypes2_sup import *\n\n')
+        sys.stdout.write('import validate_simpletypes2_sup as model_\n\n')
+        sys.stdout.write('rootObj = model_.rootClass(\n')
+        rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
+        sys.stdout.write(')\n')
+    return rootObj
+
+
+USAGE_TEXT = """
+Usage: python ???.py <infilename>
+"""
+
+
+def usage():
+    print USAGE_TEXT
+    sys.exit(1)
+
+
+def main():
+    args = sys.argv[1:]
+    if len(args) != 1:
+        usage()
+    infilename = args[0]
+    parse(infilename)
+
+
+if __name__ == '__main__':
+    #import pdb; pdb.set_trace()
+    main()
diff --git a/tests/validate_simpletypes2_sup.py b/tests/validate_simpletypes2_sup.py
new file mode 100644
index 0000000..77d9886
--- /dev/null
+++ b/tests/validate_simpletypes2_sup.py
@@ -0,0 +1,1396 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#
+# Generated  by generateDS.py.
+#
+# Command line options:
+#   ('--no-dates', '')
+#   ('--no-versions', '')
+#   ('--member-specs', 'list')
+#   ('-f', '')
+#   ('-o', 'tests/validate_simpletypes2_sup.py')
+#   ('-s', 'tests/validate_simpletypes2_sub.py')
+#   ('--super', 'validate_simpletypes2_sup')
+#
+# Command line arguments:
+#   tests/validate_simpletypes.xsd
+#
+# Command line:
+#   generateDS.py --no-dates --no-versions --member-specs="list" -f -o "tests/validate_simpletypes2_sup.py" -s "tests/validate_simpletypes2_sub.py" --super="validate_simpletypes2_sup" tests/validate_simpletypes.xsd
+#
+# Current working directory (os.getcwd()):
+#   generateds
+#
+
+import sys
+import getopt
+import re as re_
+import base64
+import datetime as datetime_
+import warnings
+
+
+Validate_simpletypes_ = True
+
+
+etree_ = None
+Verbose_import_ = False
+(
+    XMLParser_import_none, XMLParser_import_lxml,
+    XMLParser_import_elementtree
+) = range(3)
+XMLParser_import_library = None
+try:
+    # lxml
+    from lxml import etree as etree_
+    XMLParser_import_library = XMLParser_import_lxml
+    if Verbose_import_:
+        print("running with lxml.etree")
+except ImportError:
+    try:
+        # cElementTree from Python 2.5+
+        import xml.etree.cElementTree as etree_
+        XMLParser_import_library = XMLParser_import_elementtree
+        if Verbose_import_:
+            print("running with cElementTree on Python 2.5+")
+    except ImportError:
+        try:
+            # ElementTree from Python 2.5+
+            import xml.etree.ElementTree as etree_
+            XMLParser_import_library = XMLParser_import_elementtree
+            if Verbose_import_:
+                print("running with ElementTree on Python 2.5+")
+        except ImportError:
+            try:
+                # normal cElementTree install
+                import cElementTree as etree_
+                XMLParser_import_library = XMLParser_import_elementtree
+                if Verbose_import_:
+                    print("running with cElementTree")
+            except ImportError:
+                try:
+                    # normal ElementTree install
+                    import elementtree.ElementTree as etree_
+                    XMLParser_import_library = XMLParser_import_elementtree
+                    if Verbose_import_:
+                        print("running with ElementTree")
+                except ImportError:
+                    raise ImportError(
+                        "Failed to import ElementTree from any known place")
+
+
+def parsexml_(*args, **kwargs):
+    if (XMLParser_import_library == XMLParser_import_lxml and
+            'parser' not in kwargs):
+        # Use the lxml ElementTree compatible parser so that, e.g.,
+        #   we ignore comments.
+        kwargs['parser'] = etree_.ETCompatXMLParser()
+    doc = etree_.parse(*args, **kwargs)
+    return doc
+
+#
+# User methods
+#
+# Calls to the methods in these classes are generated by generateDS.py.
+# You can replace these methods by re-implementing the following class
+#   in a module named generatedssuper.py.
+
+try:
+    from generatedssuper import GeneratedsSuper
+except ImportError, exp:
+
+    class GeneratedsSuper(object):
+        tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
+        class _FixedOffsetTZ(datetime_.tzinfo):
+            def __init__(self, offset, name):
+                self.__offset = datetime_.timedelta(minutes=offset)
+                self.__name = name
+            def utcoffset(self, dt):
+                return self.__offset
+            def tzname(self, dt):
+                return self.__name
+            def dst(self, dt):
+                return None
+        def gds_format_string(self, input_data, input_name=''):
+            return input_data
+        def gds_validate_string(self, input_data, node, input_name=''):
+            if not input_data:
+                return ''
+            else:
+                return input_data
+        def gds_format_base64(self, input_data, input_name=''):
+            return base64.b64encode(input_data)
+        def gds_validate_base64(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_integer(self, input_data, input_name=''):
+            return '%d' % input_data
+        def gds_validate_integer(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_integer_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_integer_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of integers')
+            return values
+        def gds_format_float(self, input_data, input_name=''):
+            return ('%.15f' % input_data).rstrip('0')
+        def gds_validate_float(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_float_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_float_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of floats')
+            return values
+        def gds_format_double(self, input_data, input_name=''):
+            return '%e' % input_data
+        def gds_validate_double(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_double_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_double_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                try:
+                    float(value)
+                except (TypeError, ValueError):
+                    raise_parse_error(node, 'Requires sequence of doubles')
+            return values
+        def gds_format_boolean(self, input_data, input_name=''):
+            return ('%s' % input_data).lower()
+        def gds_validate_boolean(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_boolean_list(self, input_data, input_name=''):
+            return '%s' % ' '.join(input_data)
+        def gds_validate_boolean_list(self, input_data, node, input_name=''):
+            values = input_data.split()
+            for value in values:
+                if value not in ('true', '1', 'false', '0', ):
+                    raise_parse_error(
+                        node,
+                        'Requires sequence of booleans '
+                        '("true", "1", "false", "0")')
+            return values
+        def gds_validate_datetime(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_datetime(self, input_data, input_name=''):
+            if input_data.microsecond == 0:
+                _svalue = '%04d-%02d-%02dT%02d:%02d:%02d' % (
+                    input_data.year,
+                    input_data.month,
+                    input_data.day,
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                )
+            else:
+                _svalue = '%04d-%02d-%02dT%02d:%02d:%02d.%s' % (
+                    input_data.year,
+                    input_data.month,
+                    input_data.day,
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                    ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+                )
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            return _svalue
+        @classmethod
+        def gds_parse_datetime(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            time_parts = input_data.split('.')
+            if len(time_parts) > 1:
+                micro_seconds = int(float('0.' + time_parts[1]) * 1000000)
+                input_data = '%s.%s' % (time_parts[0], micro_seconds, )
+                dt = datetime_.datetime.strptime(
+                    input_data, '%Y-%m-%dT%H:%M:%S.%f')
+            else:
+                dt = datetime_.datetime.strptime(
+                    input_data, '%Y-%m-%dT%H:%M:%S')
+            dt = dt.replace(tzinfo=tz)
+            return dt
+        def gds_validate_date(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_date(self, input_data, input_name=''):
+            _svalue = '%04d-%02d-%02d' % (
+                input_data.year,
+                input_data.month,
+                input_data.day,
+            )
+            try:
+                if input_data.tzinfo is not None:
+                    tzoff = input_data.tzinfo.utcoffset(input_data)
+                    if tzoff is not None:
+                        total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                        if total_seconds == 0:
+                            _svalue += 'Z'
+                        else:
+                            if total_seconds < 0:
+                                _svalue += '-'
+                                total_seconds *= -1
+                            else:
+                                _svalue += '+'
+                            hours = total_seconds // 3600
+                            minutes = (total_seconds - (hours * 3600)) // 60
+                            _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            except AttributeError:
+                pass
+            return _svalue
+        @classmethod
+        def gds_parse_date(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            dt = datetime_.datetime.strptime(input_data, '%Y-%m-%d')
+            dt = dt.replace(tzinfo=tz)
+            return dt.date()
+        def gds_validate_time(self, input_data, node, input_name=''):
+            return input_data
+        def gds_format_time(self, input_data, input_name=''):
+            if input_data.microsecond == 0:
+                _svalue = '%02d:%02d:%02d' % (
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                )
+            else:
+                _svalue = '%02d:%02d:%02d.%s' % (
+                    input_data.hour,
+                    input_data.minute,
+                    input_data.second,
+                    ('%f' % (float(input_data.microsecond) / 1000000))[2:],
+                )
+            if input_data.tzinfo is not None:
+                tzoff = input_data.tzinfo.utcoffset(input_data)
+                if tzoff is not None:
+                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
+                    if total_seconds == 0:
+                        _svalue += 'Z'
+                    else:
+                        if total_seconds < 0:
+                            _svalue += '-'
+                            total_seconds *= -1
+                        else:
+                            _svalue += '+'
+                        hours = total_seconds // 3600
+                        minutes = (total_seconds - (hours * 3600)) // 60
+                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
+            return _svalue
+        @classmethod
+        def gds_parse_time(cls, input_data):
+            tz = None
+            if input_data[-1] == 'Z':
+                tz = GeneratedsSuper._FixedOffsetTZ(0, 'UTC')
+                input_data = input_data[:-1]
+            else:
+                results = GeneratedsSuper.tzoff_pattern.search(input_data)
+                if results is not None:
+                    tzoff_parts = results.group(2).split(':')
+                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
+                    if results.group(1) == '-':
+                        tzoff *= -1
+                    tz = GeneratedsSuper._FixedOffsetTZ(
+                        tzoff, results.group(0))
+                    input_data = input_data[:-6]
+            if len(input_data.split('.')) > 1:
+                dt = datetime_.datetime.strptime(input_data, '%H:%M:%S.%f')
+            else:
+                dt = datetime_.datetime.strptime(input_data, '%H:%M:%S')
+            dt = dt.replace(tzinfo=tz)
+            return dt.time()
+        def gds_str_lower(self, instring):
+            return instring.lower()
+        def get_path_(self, node):
+            path_list = []
+            self.get_path_list_(node, path_list)
+            path_list.reverse()
+            path = '/'.join(path_list)
+            return path
+        Tag_strip_pattern_ = re_.compile(r'\{.*\}')
+        def get_path_list_(self, node, path_list):
+            if node is None:
+                return
+            tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag)
+            if tag:
+                path_list.append(tag)
+            self.get_path_list_(node.getparent(), path_list)
+        def get_class_obj_(self, node, default_class=None):
+            class_obj1 = default_class
+            if 'xsi' in node.nsmap:
+                classname = node.get('{%s}type' % node.nsmap['xsi'])
+                if classname is not None:
+                    names = classname.split(':')
+                    if len(names) == 2:
+                        classname = names[1]
+                    class_obj2 = globals().get(classname)
+                    if class_obj2 is not None:
+                        class_obj1 = class_obj2
+            return class_obj1
+        def gds_build_any(self, node, type_name=None):
+            return None
+        @classmethod
+        def gds_reverse_node_mapping(cls, mapping):
+            return dict(((v, k) for k, v in mapping.iteritems()))
+
+
+#
+# If you have installed IPython you can uncomment and use the following.
+# IPython is available from http://ipython.scipy.org/.
+#
+
+## from IPython.Shell import IPShellEmbed
+## args = ''
+## ipshell = IPShellEmbed(args,
+##     banner = 'Dropping into IPython',
+##     exit_msg = 'Leaving Interpreter, back to program.')
+
+# Then use the following line where and when you want to drop into the
+# IPython shell:
+#    ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')
+
+#
+# Globals
+#
+
+ExternalEncoding = 'ascii'
+Tag_pattern_ = re_.compile(r'({.*})?(.*)')
+String_cleanup_pat_ = re_.compile(r"[\n\r\s]+")
+Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)')
+
+#
+# Support/utility functions.
+#
+
+
+def showIndent(outfile, level, pretty_print=True):
+    if pretty_print:
+        for idx in range(level):
+            outfile.write('    ')
+
+
+def quote_xml(inStr):
+    if not inStr:
+        return ''
+    s1 = (isinstance(inStr, basestring) and inStr or
+          '%s' % inStr)
+    s1 = s1.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    return s1
+
+
+def quote_attrib(inStr):
+    s1 = (isinstance(inStr, basestring) and inStr or
+          '%s' % inStr)
+    s1 = s1.replace('&', '&amp;')
+    s1 = s1.replace('<', '&lt;')
+    s1 = s1.replace('>', '&gt;')
+    if '"' in s1:
+        if "'" in s1:
+            s1 = '"%s"' % s1.replace('"', "&quot;")
+        else:
+            s1 = "'%s'" % s1
+    else:
+        s1 = '"%s"' % s1
+    return s1
+
+
+def quote_python(inStr):
+    s1 = inStr
+    if s1.find("'") == -1:
+        if s1.find('\n') == -1:
+            return "'%s'" % s1
+        else:
+            return "'''%s'''" % s1
+    else:
+        if s1.find('"') != -1:
+            s1 = s1.replace('"', '\\"')
+        if s1.find('\n') == -1:
+            return '"%s"' % s1
+        else:
+            return '"""%s"""' % s1
+
+
+def get_all_text_(node):
+    if node.text is not None:
+        text = node.text
+    else:
+        text = ''
+    for child in node:
+        if child.tail is not None:
+            text += child.tail
+    return text
+
+
+def find_attr_value_(attr_name, node):
+    attrs = node.attrib
+    attr_parts = attr_name.split(':')
+    value = None
+    if len(attr_parts) == 1:
+        value = attrs.get(attr_name)
+    elif len(attr_parts) == 2:
+        prefix, name = attr_parts
+        namespace = node.nsmap.get(prefix)
+        if namespace is not None:
+            value = attrs.get('{%s}%s' % (namespace, name, ))
+    return value
+
+
+class GDSParseError(Exception):
+    pass
+
+
+def raise_parse_error(node, msg):
+    if XMLParser_import_library == XMLParser_import_lxml:
+        msg = '%s (element %s/line %d)' % (
+            msg, node.tag, node.sourceline, )
+    else:
+        msg = '%s (element %s)' % (msg, node.tag, )
+    raise GDSParseError(msg)
+
+
+class MixedContainer:
+    # Constants for category:
+    CategoryNone = 0
+    CategoryText = 1
+    CategorySimple = 2
+    CategoryComplex = 3
+    # Constants for content_type:
+    TypeNone = 0
+    TypeText = 1
+    TypeString = 2
+    TypeInteger = 3
+    TypeFloat = 4
+    TypeDecimal = 5
+    TypeDouble = 6
+    TypeBoolean = 7
+    TypeBase64 = 8
+    def __init__(self, category, content_type, name, value):
+        self.category = category
+        self.content_type = content_type
+        self.name = name
+        self.value = value
+    def getCategory(self):
+        return self.category
+    def getContenttype(self, content_type):
+        return self.content_type
+    def getValue(self):
+        return self.value
+    def getName(self):
+        return self.name
+    def export(self, outfile, level, name, namespace, pretty_print=True):
+        if self.category == MixedContainer.CategoryText:
+            # Prevent exporting empty content as empty lines.
+            if self.value.strip():
+                outfile.write(self.value)
+        elif self.category == MixedContainer.CategorySimple:
+            self.exportSimple(outfile, level, name)
+        else:    # category == MixedContainer.CategoryComplex
+            self.value.export(outfile, level, namespace, name, pretty_print)
+    def exportSimple(self, outfile, level, name):
+        if self.content_type == MixedContainer.TypeString:
+            outfile.write('<%s>%s</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeInteger or \
+                self.content_type == MixedContainer.TypeBoolean:
+            outfile.write('<%s>%d</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeFloat or \
+                self.content_type == MixedContainer.TypeDecimal:
+            outfile.write('<%s>%f</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeDouble:
+            outfile.write('<%s>%g</%s>' % (
+                self.name, self.value, self.name))
+        elif self.content_type == MixedContainer.TypeBase64:
+            outfile.write('<%s>%s</%s>' % (
+                self.name, base64.b64encode(self.value), self.name))
+    def to_etree(self, element):
+        if self.category == MixedContainer.CategoryText:
+            # Prevent exporting empty content as empty lines.
+            if self.value.strip():
+                if len(element) > 0:
+                    if element[-1].tail is None:
+                        element[-1].tail = self.value
+                    else:
+                        element[-1].tail += self.value
+                else:
+                    if element.text is None:
+                        element.text = self.value
+                    else:
+                        element.text += self.value
+        elif self.category == MixedContainer.CategorySimple:
+            subelement = etree_.SubElement(element, '%s' % self.name)
+            subelement.text = self.to_etree_simple()
+        else:    # category == MixedContainer.CategoryComplex
+            self.value.to_etree(element)
+    def to_etree_simple(self):
+        if self.content_type == MixedContainer.TypeString:
+            text = self.value
+        elif (self.content_type == MixedContainer.TypeInteger or
+                self.content_type == MixedContainer.TypeBoolean):
+            text = '%d' % self.value
+        elif (self.content_type == MixedContainer.TypeFloat or
+                self.content_type == MixedContainer.TypeDecimal):
+            text = '%f' % self.value
+        elif self.content_type == MixedContainer.TypeDouble:
+            text = '%g' % self.value
+        elif self.content_type == MixedContainer.TypeBase64:
+            text = '%s' % base64.b64encode(self.value)
+        return text
+    def exportLiteral(self, outfile, level, name):
+        if self.category == MixedContainer.CategoryText:
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+                    self.category, self.content_type, self.name, self.value))
+        elif self.category == MixedContainer.CategorySimple:
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s", "%s"),\n' % (
+                    self.category, self.content_type, self.name, self.value))
+        else:    # category == MixedContainer.CategoryComplex
+            showIndent(outfile, level)
+            outfile.write(
+                'model_.MixedContainer(%d, %d, "%s",\n' % (
+                    self.category, self.content_type, self.name,))
+            self.value.exportLiteral(outfile, level + 1)
+            showIndent(outfile, level)
+            outfile.write(')\n')
+
+
+class MemberSpec_(object):
+    def __init__(self, name='', data_type='', container=0):
+        self.name = name
+        self.data_type = data_type
+        self.container = container
+    def set_name(self, name): self.name = name
+    def get_name(self): return self.name
+    def set_data_type(self, data_type): self.data_type = data_type
+    def get_data_type_chain(self): return self.data_type
+    def get_data_type(self):
+        if isinstance(self.data_type, list):
+            if len(self.data_type) > 0:
+                return self.data_type[-1]
+            else:
+                return 'xs:string'
+        else:
+            return self.data_type
+    def set_container(self, container): self.container = container
+    def get_container(self): return self.container
+
+
+def _cast(typ, value):
+    if typ is None or value is None:
+        return value
+    return typ(value)
+
+#
+# Data representation classes.
+#
+
+
+class containerType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('sample1', 'simpleOneType', 1),
+        MemberSpec_('sample2_bad', 'simpleOneType', 1),
+        MemberSpec_('sample3_bad', 'simpleOneType', 1),
+        MemberSpec_('sample2', 'simpleTwoType', 1),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, sample1=None, sample2_bad=None, sample3_bad=None, sample2=None):
+        self.original_tagname_ = None
+        if sample1 is None:
+            self.sample1 = []
+        else:
+            self.sample1 = sample1
+        if sample2_bad is None:
+            self.sample2_bad = []
+        else:
+            self.sample2_bad = sample2_bad
+        if sample3_bad is None:
+            self.sample3_bad = []
+        else:
+            self.sample3_bad = sample3_bad
+        if sample2 is None:
+            self.sample2 = []
+        else:
+            self.sample2 = sample2
+    def factory(*args_, **kwargs_):
+        if containerType.subclass:
+            return containerType.subclass(*args_, **kwargs_)
+        else:
+            return containerType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_sample1(self): return self.sample1
+    def set_sample1(self, sample1): self.sample1 = sample1
+    def add_sample1(self, value): self.sample1.append(value)
+    def insert_sample1_at(self, index, value): self.sample1.insert(index, value)
+    def replace_sample1_at(self, index, value): self.sample1[index] = value
+    def get_sample2_bad(self): return self.sample2_bad
+    def set_sample2_bad(self, sample2_bad): self.sample2_bad = sample2_bad
+    def add_sample2_bad(self, value): self.sample2_bad.append(value)
+    def insert_sample2_bad_at(self, index, value): self.sample2_bad.insert(index, value)
+    def replace_sample2_bad_at(self, index, value): self.sample2_bad[index] = value
+    def get_sample3_bad(self): return self.sample3_bad
+    def set_sample3_bad(self, sample3_bad): self.sample3_bad = sample3_bad
+    def add_sample3_bad(self, value): self.sample3_bad.append(value)
+    def insert_sample3_bad_at(self, index, value): self.sample3_bad.insert(index, value)
+    def replace_sample3_bad_at(self, index, value): self.sample3_bad[index] = value
+    def get_sample2(self): return self.sample2
+    def set_sample2(self, sample2): self.sample2 = sample2
+    def add_sample2(self, value): self.sample2.append(value)
+    def insert_sample2_at(self, index, value): self.sample2.insert(index, value)
+    def replace_sample2_at(self, index, value): self.sample2[index] = value
+    def hasContent_(self):
+        if (
+            self.sample1 or
+            self.sample2_bad or
+            self.sample3_bad or
+            self.sample2
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='containerType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='containerType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='containerType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='containerType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='containerType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        for sample1_ in self.sample1:
+            sample1_.export(outfile, level, namespace_, name_='sample1', pretty_print=pretty_print)
+        for sample2_bad_ in self.sample2_bad:
+            sample2_bad_.export(outfile, level, namespace_, name_='sample2_bad', pretty_print=pretty_print)
+        for sample3_bad_ in self.sample3_bad:
+            sample3_bad_.export(outfile, level, namespace_, name_='sample3_bad', pretty_print=pretty_print)
+        for sample2_ in self.sample2:
+            sample2_.export(outfile, level, namespace_, name_='sample2', pretty_print=pretty_print)
+    def exportLiteral(self, outfile, level, name_='containerType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        showIndent(outfile, level)
+        outfile.write('sample1=[\n')
+        level += 1
+        for sample1_ in self.sample1:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample1_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample2_bad=[\n')
+        level += 1
+        for sample2_bad_ in self.sample2_bad:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample2_bad_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample3_bad=[\n')
+        level += 1
+        for sample3_bad_ in self.sample3_bad:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleOneType(\n')
+            sample3_bad_.exportLiteral(outfile, level, name_='simpleOneType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+        showIndent(outfile, level)
+        outfile.write('sample2=[\n')
+        level += 1
+        for sample2_ in self.sample2:
+            showIndent(outfile, level)
+            outfile.write('model_.simpleTwoType(\n')
+            sample2_.exportLiteral(outfile, level, name_='simpleTwoType')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+        level -= 1
+        showIndent(outfile, level)
+        outfile.write('],\n')
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'sample1':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample1.append(obj_)
+            obj_.original_tagname_ = 'sample1'
+        elif nodeName_ == 'sample2_bad':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample2_bad.append(obj_)
+            obj_.original_tagname_ = 'sample2_bad'
+        elif nodeName_ == 'sample3_bad':
+            obj_ = simpleOneType.factory()
+            obj_.build(child_)
+            self.sample3_bad.append(obj_)
+            obj_.original_tagname_ = 'sample3_bad'
+        elif nodeName_ == 'sample2':
+            obj_ = simpleTwoType.factory()
+            obj_.build(child_)
+            self.sample2.append(obj_)
+            obj_.original_tagname_ = 'sample2'
+# end class containerType
+
+
+class simpleOneType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('token_enum_value', ['token_enum_st', 'xs:NMTOKEN'], 0),
+        MemberSpec_('token_enum_value', ['token_enum_st', 'xs:NMTOKEN'], 0),
+        MemberSpec_('integer_range_incl_value', ['integer_range_incl_st', 'xs:integer'], 0),
+        MemberSpec_('integer_range_excl_value', ['integer_range_excl_st', 'xs:integer'], 0),
+        MemberSpec_('min_max_length_value', ['min_max_length_st', 'xs:string'], 0),
+        MemberSpec_('length_value', ['length_st', 'xs:string'], 0),
+        MemberSpec_('totaldigits_value', ['totaldigits_st', 'xs:float'], 0),
+        MemberSpec_('anonymous_float_value', ['anonymous_float_valueType', 'xs:float'], 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, token_enum_value=None, integer_range_incl_value=None, integer_range_excl_value=None, min_max_length_value=None, length_value=None, totaldigits_value=None, anonymous_float_value=None):
+        self.original_tagname_ = None
+        self.token_enum_value = token_enum_value
+        self.validate_token_enum_st(self.token_enum_value)
+        self.token_enum_value = token_enum_value
+        self.validate_token_enum_st(self.token_enum_value)
+        self.integer_range_incl_value = integer_range_incl_value
+        self.validate_integer_range_incl_st(self.integer_range_incl_value)
+        self.integer_range_excl_value = integer_range_excl_value
+        self.validate_integer_range_excl_st(self.integer_range_excl_value)
+        self.min_max_length_value = min_max_length_value
+        self.validate_min_max_length_st(self.min_max_length_value)
+        self.length_value = length_value
+        self.validate_length_st(self.length_value)
+        self.totaldigits_value = totaldigits_value
+        self.validate_totaldigits_st(self.totaldigits_value)
+        self.anonymous_float_value = anonymous_float_value
+        self.validate_anonymous_float_valueType(self.anonymous_float_value)
+    def factory(*args_, **kwargs_):
+        if simpleOneType.subclass:
+            return simpleOneType.subclass(*args_, **kwargs_)
+        else:
+            return simpleOneType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_token_enum_value(self): return self.token_enum_value
+    def set_token_enum_value(self, token_enum_value): self.token_enum_value = token_enum_value
+    def get_token_enum_value(self): return self.token_enum_value
+    def set_token_enum_value(self, token_enum_value): self.token_enum_value = token_enum_value
+    def get_integer_range_incl_value(self): return self.integer_range_incl_value
+    def set_integer_range_incl_value(self, integer_range_incl_value): self.integer_range_incl_value = integer_range_incl_value
+    def get_integer_range_excl_value(self): return self.integer_range_excl_value
+    def set_integer_range_excl_value(self, integer_range_excl_value): self.integer_range_excl_value = integer_range_excl_value
+    def get_min_max_length_value(self): return self.min_max_length_value
+    def set_min_max_length_value(self, min_max_length_value): self.min_max_length_value = min_max_length_value
+    def get_length_value(self): return self.length_value
+    def set_length_value(self, length_value): self.length_value = length_value
+    def get_totaldigits_value(self): return self.totaldigits_value
+    def set_totaldigits_value(self, totaldigits_value): self.totaldigits_value = totaldigits_value
+    def get_anonymous_float_value(self): return self.anonymous_float_value
+    def set_anonymous_float_value(self, anonymous_float_value): self.anonymous_float_value = anonymous_float_value
+    def validate_token_enum_st(self, value):
+        # Validate type token_enum_st, a restriction on xs:NMTOKEN.
+        if value is not None and Validate_simpletypes_:
+           enumerations = ['float', 'int', 'Name', 'token']
+           enumeration_respectee = False
+           for enum in enumerations:
+               if value == enum:
+                   enumeration_respectee = True
+                   break
+           if not enumeration_respectee:
+               warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on token_enum_st' % {"value" : value.encode("utf-8")} )
+    def validate_integer_range_incl_st(self, value):
+        # Validate type integer_range_incl_st, a restriction on xs:integer.
+        if value is not None and Validate_simpletypes_:
+           if value <= -5:
+               warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on integer_range_incl_st' % {"value" : value} )
+           if value >= 10:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on integer_range_incl_st' % {"value" : value} )
+    def validate_integer_range_excl_st(self, value):
+        # Validate type integer_range_excl_st, a restriction on xs:integer.
+        if value is not None and Validate_simpletypes_:
+           if value < -5:
+               warnings.warn('Value "%(value)s" does not match xsd minExclusive restriction on integer_range_excl_st' % {"value" : value} )
+           if value > 10:
+               warnings.warn('Value "%(value)s" does not match xsd maxExclusive restriction on integer_range_excl_st' % {"value" : value} )
+    def validate_min_max_length_st(self, value):
+        # Validate type min_max_length_st, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 10:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+           if len(value) > 20:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+    def validate_length_st(self, value):
+        # Validate type length_st, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) != 10:
+               warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+    def validate_totaldigits_st(self, value):
+        # Validate type totaldigits_st, a restriction on xs:float.
+        if value is not None and Validate_simpletypes_:
+           if len(str(value)) >= 15:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on totaldigits_st' % {"value" : value} )
+    def validate_anonymous_float_valueType(self, value):
+        # Validate type anonymous_float_valueType, a restriction on xs:float.
+        if value is not None and Validate_simpletypes_:
+           if value <= 1.1:
+               warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+           if value >= 4.4:
+               warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+    def hasContent_(self):
+        if (
+            self.token_enum_value is not None or
+            self.token_enum_value is not None or
+            self.integer_range_incl_value is not None or
+            self.integer_range_excl_value is not None or
+            self.min_max_length_value is not None or
+            self.length_value is not None or
+            self.totaldigits_value is not None or
+            self.anonymous_float_value is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='simpleOneType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='simpleOneType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='simpleOneType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='simpleOneType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='simpleOneType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.token_enum_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stoken_enum_value>%s</%stoken_enum_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.token_enum_value).encode(ExternalEncoding), input_name='token_enum_value'), namespace_, eol_))
+        if self.token_enum_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stoken_enum_value>%s</%stoken_enum_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.token_enum_value).encode(ExternalEncoding), input_name='token_enum_value'), namespace_, eol_))
+        if self.integer_range_incl_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sinteger_range_incl_value>%s</%sinteger_range_incl_value>%s' % (namespace_, self.gds_format_integer(self.integer_range_incl_value, input_name='integer_range_incl_value'), namespace_, eol_))
+        if self.integer_range_excl_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sinteger_range_excl_value>%s</%sinteger_range_excl_value>%s' % (namespace_, self.gds_format_integer(self.integer_range_excl_value, input_name='integer_range_excl_value'), namespace_, eol_))
+        if self.min_max_length_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%smin_max_length_value>%s</%smin_max_length_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.min_max_length_value).encode(ExternalEncoding), input_name='min_max_length_value'), namespace_, eol_))
+        if self.length_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%slength_value>%s</%slength_value>%s' % (namespace_, self.gds_format_string(quote_xml(self.length_value).encode(ExternalEncoding), input_name='length_value'), namespace_, eol_))
+        if self.totaldigits_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%stotaldigits_value>%s</%stotaldigits_value>%s' % (namespace_, self.gds_format_float(self.totaldigits_value, input_name='totaldigits_value'), namespace_, eol_))
+        if self.anonymous_float_value is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sanonymous_float_value>%s</%sanonymous_float_value>%s' % (namespace_, self.gds_format_float(self.anonymous_float_value, input_name='anonymous_float_value'), namespace_, eol_))
+    def exportLiteral(self, outfile, level, name_='simpleOneType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.token_enum_value is not None:
+            showIndent(outfile, level)
+            outfile.write('token_enum_value=%s,\n' % quote_python(self.token_enum_value).encode(ExternalEncoding))
+        if self.token_enum_value is not None:
+            showIndent(outfile, level)
+            outfile.write('token_enum_value=%s,\n' % quote_python(self.token_enum_value).encode(ExternalEncoding))
+        if self.integer_range_incl_value is not None:
+            showIndent(outfile, level)
+            outfile.write('integer_range_incl_value=%d,\n' % self.integer_range_incl_value)
+        if self.integer_range_excl_value is not None:
+            showIndent(outfile, level)
+            outfile.write('integer_range_excl_value=%d,\n' % self.integer_range_excl_value)
+        if self.min_max_length_value is not None:
+            showIndent(outfile, level)
+            outfile.write('min_max_length_value=%s,\n' % quote_python(self.min_max_length_value).encode(ExternalEncoding))
+        if self.length_value is not None:
+            showIndent(outfile, level)
+            outfile.write('length_value=%s,\n' % quote_python(self.length_value).encode(ExternalEncoding))
+        if self.totaldigits_value is not None:
+            showIndent(outfile, level)
+            outfile.write('totaldigits_value=%f,\n' % self.totaldigits_value)
+        if self.anonymous_float_value is not None:
+            showIndent(outfile, level)
+            outfile.write('anonymous_float_value=%f,\n' % self.anonymous_float_value)
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'token_enum_value':
+            token_enum_value_ = child_.text
+            token_enum_value_ = self.gds_validate_string(token_enum_value_, node, 'token_enum_value')
+            self.token_enum_value = token_enum_value_
+            self.validate_token_enum_st(self.token_enum_value)    # validate type token_enum_st
+        elif nodeName_ == 'token_enum_value':
+            token_enum_value_ = child_.text
+            token_enum_value_ = self.gds_validate_string(token_enum_value_, node, 'token_enum_value')
+            self.token_enum_value = token_enum_value_
+            self.validate_token_enum_st(self.token_enum_value)    # validate type token_enum_st
+        elif nodeName_ == 'integer_range_incl_value':
+            sval_ = child_.text
+            try:
+                ival_ = int(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires integer: %s' % exp)
+            ival_ = self.gds_validate_integer(ival_, node, 'integer_range_incl_value')
+            self.integer_range_incl_value = ival_
+            self.validate_integer_range_incl_st(self.integer_range_incl_value)    # validate type integer_range_incl_st
+        elif nodeName_ == 'integer_range_excl_value':
+            sval_ = child_.text
+            try:
+                ival_ = int(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires integer: %s' % exp)
+            ival_ = self.gds_validate_integer(ival_, node, 'integer_range_excl_value')
+            self.integer_range_excl_value = ival_
+            self.validate_integer_range_excl_st(self.integer_range_excl_value)    # validate type integer_range_excl_st
+        elif nodeName_ == 'min_max_length_value':
+            min_max_length_value_ = child_.text
+            min_max_length_value_ = self.gds_validate_string(min_max_length_value_, node, 'min_max_length_value')
+            self.min_max_length_value = min_max_length_value_
+            self.validate_min_max_length_st(self.min_max_length_value)    # validate type min_max_length_st
+        elif nodeName_ == 'length_value':
+            length_value_ = child_.text
+            length_value_ = self.gds_validate_string(length_value_, node, 'length_value')
+            self.length_value = length_value_
+            self.validate_length_st(self.length_value)    # validate type length_st
+        elif nodeName_ == 'totaldigits_value':
+            sval_ = child_.text
+            try:
+                fval_ = float(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires float or double: %s' % exp)
+            fval_ = self.gds_validate_float(fval_, node, 'totaldigits_value')
+            self.totaldigits_value = fval_
+            self.validate_totaldigits_st(self.totaldigits_value)    # validate type totaldigits_st
+        elif nodeName_ == 'anonymous_float_value':
+            sval_ = child_.text
+            try:
+                fval_ = float(sval_)
+            except (TypeError, ValueError), exp:
+                raise_parse_error(child_, 'requires float or double: %s' % exp)
+            fval_ = self.gds_validate_float(fval_, node, 'anonymous_float_value')
+            self.anonymous_float_value = fval_
+            self.validate_anonymous_float_valueType(self.anonymous_float_value)    # validate type anonymous_float_valueType
+# end class simpleOneType
+
+
+class simpleTwoType(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('Foo', 'FooType1', 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, Foo=None):
+        self.original_tagname_ = None
+        self.Foo = Foo
+    def factory(*args_, **kwargs_):
+        if simpleTwoType.subclass:
+            return simpleTwoType.subclass(*args_, **kwargs_)
+        else:
+            return simpleTwoType(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_Foo(self): return self.Foo
+    def set_Foo(self, Foo): self.Foo = Foo
+    def hasContent_(self):
+        if (
+            self.Foo is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='simpleTwoType', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='simpleTwoType')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='simpleTwoType', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='simpleTwoType'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='simpleTwoType', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.Foo is not None:
+            self.Foo.export(outfile, level, namespace_, name_='Foo', pretty_print=pretty_print)
+    def exportLiteral(self, outfile, level, name_='simpleTwoType'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.Foo is not None:
+            showIndent(outfile, level)
+            outfile.write('Foo=model_.FooType1(\n')
+            self.Foo.exportLiteral(outfile, level, name_='Foo')
+            showIndent(outfile, level)
+            outfile.write('),\n')
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'Foo':
+            obj_ = FooType1.factory()
+            obj_.build(child_)
+            self.Foo = obj_
+            obj_.original_tagname_ = 'Foo'
+# end class simpleTwoType
+
+
+class FooType1(GeneratedsSuper):
+    member_data_items_ = [
+        MemberSpec_('FooType', ['FooTypeType', 'xs:string'], 0),
+    ]
+    subclass = None
+    superclass = None
+    def __init__(self, FooType=None):
+        self.original_tagname_ = None
+        self.FooType = FooType
+        self.validate_FooTypeType(self.FooType)
+    def factory(*args_, **kwargs_):
+        if FooType1.subclass:
+            return FooType1.subclass(*args_, **kwargs_)
+        else:
+            return FooType1(*args_, **kwargs_)
+    factory = staticmethod(factory)
+    def get_FooType(self): return self.FooType
+    def set_FooType(self, FooType): self.FooType = FooType
+    def validate_FooTypeType(self, value):
+        # Validate type FooTypeType, a restriction on xs:string.
+        if value is not None and Validate_simpletypes_:
+           if len(value) < 12:
+               warnings.warn('Value "%(value)s" does not match xsd minLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+           if len(value) > 24:
+               warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on FooTypeType' % {"value" : value.encode("utf-8")} )
+    def hasContent_(self):
+        if (
+            self.FooType is not None
+        ):
+            return True
+        else:
+            return False
+    def export(self, outfile, level, namespace_='', name_='FooType1', namespacedef_='', pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.original_tagname_ is not None:
+            name_ = self.original_tagname_
+        showIndent(outfile, level, pretty_print)
+        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
+        already_processed = set()
+        self.exportAttributes(outfile, level, already_processed, namespace_, name_='FooType1')
+        if self.hasContent_():
+            outfile.write('>%s' % (eol_, ))
+            self.exportChildren(outfile, level + 1, namespace_='', name_='FooType1', pretty_print=pretty_print)
+            showIndent(outfile, level, pretty_print)
+            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
+        else:
+            outfile.write('/>%s' % (eol_, ))
+    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='FooType1'):
+        pass
+    def exportChildren(self, outfile, level, namespace_='', name_='FooType1', fromsubclass_=False, pretty_print=True):
+        if pretty_print:
+            eol_ = '\n'
+        else:
+            eol_ = ''
+        if self.FooType is not None:
+            showIndent(outfile, level, pretty_print)
+            outfile.write('<%sFooType>%s</%sFooType>%s' % (namespace_, self.gds_format_string(quote_xml(self.FooType).encode(ExternalEncoding), input_name='FooType'), namespace_, eol_))
+    def exportLiteral(self, outfile, level, name_='FooType1'):
+        level += 1
+        already_processed = set()
+        self.exportLiteralAttributes(outfile, level, already_processed, name_)
+        if self.hasContent_():
+            self.exportLiteralChildren(outfile, level, name_)
+    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
+        pass
+    def exportLiteralChildren(self, outfile, level, name_):
+        if self.FooType is not None:
+            showIndent(outfile, level)
+            outfile.write('FooType=%s,\n' % quote_python(self.FooType).encode(ExternalEncoding))
+    def build(self, node):
+        already_processed = set()
+        self.buildAttributes(node, node.attrib, already_processed)
+        for child in node:
+            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
+            self.buildChildren(child, node, nodeName_)
+        return self
+    def buildAttributes(self, node, attrs, already_processed):
+        pass
+    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
+        if nodeName_ == 'FooType':
+            FooType_ = child_.text
+            FooType_ = self.gds_validate_string(FooType_, node, 'FooType')
+            self.FooType = FooType_
+            self.validate_FooTypeType(self.FooType)    # validate type FooTypeType
+# end class FooType1
+
+
+GDSClassesMapping = {
+    'container': containerType,
+    'sample2_bad': simpleOneType,
+    'sample1': simpleOneType,
+    'sample3_bad': simpleOneType,
+    'sample2': simpleTwoType,
+    'Foo': FooType1,
+}
+
+
+USAGE_TEXT = """
+Usage: python <Parser>.py [ -s ] <in_xml_file>
+"""
+
+
+def usage():
+    print USAGE_TEXT
+    sys.exit(1)
+
+
+def get_root_tag(node):
+    tag = Tag_pattern_.match(node.tag).groups()[-1]
+    rootClass = GDSClassesMapping.get(tag)
+    if rootClass is None:
+        rootClass = globals().get(tag)
+    return tag, rootClass
+
+
+def parse(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='',
+            pretty_print=True)
+    return rootObj
+
+
+def parseEtree(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    mapping = {}
+    rootElement = rootObj.to_etree(None, name_=rootTag, mapping_=mapping)
+    reverse_mapping = rootObj.gds_reverse_node_mapping(mapping)
+    if not silence:
+        content = etree_.tostring(
+            rootElement, pretty_print=True,
+            xml_declaration=True, encoding="utf-8")
+        sys.stdout.write(content)
+        sys.stdout.write('\n')
+    return rootObj, rootElement, mapping, reverse_mapping
+
+
+def parseString(inString, silence=False):
+    from StringIO import StringIO
+    doc = parsexml_(StringIO(inString))
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('<?xml version="1.0" ?>\n')
+        rootObj.export(
+            sys.stdout, 0, name_=rootTag,
+            namespacedef_='')
+    return rootObj
+
+
+def parseLiteral(inFileName, silence=False):
+    doc = parsexml_(inFileName)
+    rootNode = doc.getroot()
+    rootTag, rootClass = get_root_tag(rootNode)
+    if rootClass is None:
+        rootTag = 'containerType'
+        rootClass = containerType
+    rootObj = rootClass.factory()
+    rootObj.build(rootNode)
+    # Enable Python to collect the space used by the DOM.
+    doc = None
+    if not silence:
+        sys.stdout.write('#from validate_simpletypes2_sup import *\n\n')
+        sys.stdout.write('import validate_simpletypes2_sup as model_\n\n')
+        sys.stdout.write('rootObj = model_.rootClass(\n')
+        rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
+        sys.stdout.write(')\n')
+    return rootObj
+
+
+def main():
+    args = sys.argv[1:]
+    if len(args) == 1:
+        parse(args[0])
+    else:
+        usage()
+
+
+if __name__ == '__main__':
+    #import pdb; pdb.set_trace()
+    main()
+
+
+__all__ = [
+    "FooType1",
+    "containerType",
+    "simpleOneType",
+    "simpleTwoType"
+]
diff --git a/tests/validate_simpletypes2_warnings.txt b/tests/validate_simpletypes2_warnings.txt
new file mode 100644
index 0000000..39f7751
--- /dev/null
+++ b/tests/validate_simpletypes2_warnings.txt
@@ -0,0 +1,20 @@
+tests/validate_simpletypes2_sup.py:889: UserWarning: Value "floatxx" does not match xsd enumeration restriction on token_enum_st
+  warnings.warn('Value "%(value)s" does not match xsd enumeration restriction on token_enum_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:896: UserWarning: Value "22" does not match xsd maxInclusive restriction on integer_range_incl_st
+  warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on integer_range_incl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:901: UserWarning: Value "-40" does not match xsd minExclusive restriction on integer_range_excl_st
+  warnings.warn('Value "%(value)s" does not match xsd minExclusive restriction on integer_range_excl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:908: UserWarning: Value "mno pqr" does not match xsd minLength restriction on min_max_length_st
+  warnings.warn('Value "%(value)s" does not match xsd minLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:915: UserWarning: Value "012345" does not match xsd length restriction on length_st
+  warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:925: UserWarning: Value "0.2" does not match xsd minInclusive restriction on anonymous_float_valueType
+  warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on anonymous_float_valueType' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:894: UserWarning: Value "-50" does not match xsd minInclusive restriction on integer_range_incl_st
+  warnings.warn('Value "%(value)s" does not match xsd minInclusive restriction on integer_range_incl_st' % {"value" : value} )
+tests/validate_simpletypes2_sup.py:910: UserWarning: Value "asdf asdf asdf adf asdf asdf" does not match xsd maxLength restriction on min_max_length_st
+  warnings.warn('Value "%(value)s" does not match xsd maxLength restriction on min_max_length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:915: UserWarning: Value "01234567890" does not match xsd length restriction on length_st
+  warnings.warn('Value "%(value)s" does not match xsd length restriction on length_st' % {"value" : value.encode("utf-8")} )
+tests/validate_simpletypes2_sup.py:927: UserWarning: Value "6.6" does not match xsd maxInclusive restriction on anonymous_float_valueType
+  warnings.warn('Value "%(value)s" does not match xsd maxInclusive restriction on anonymous_float_valueType' % {"value" : value} )
diff --git a/tutorial/generateds_tutorial.html b/tutorial/generateds_tutorial.html
index 4229ff0..4ede248 100644
--- a/tutorial/generateds_tutorial.html
+++ b/tutorial/generateds_tutorial.html
@@ -219,7 +219,7 @@ They are used by updateversion.py. -->
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.13a</td>
+<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.14a</td>
 </tr>
 </tbody>
 </table>
@@ -228,7 +228,7 @@ They are used by updateversion.py. -->
 <col class="field-name" />
 <col class="field-body" />
 <tbody valign="top">
-<tr class="field"><th class="field-name">date:</th><td class="field-body">September 09, 2014</td>
+<tr class="field"><th class="field-name">date:</th><td class="field-body">October 08, 2014</td>
 </tr>
 </tbody>
 </table>
@@ -1210,7 +1210,7 @@ named <tt class="docutils literal">garden_api.py</tt>, you can create an instanc
 <div class="footer">
 <hr class="footer" />
 <a class="reference external" href="generateds_tutorial.txt">View document source</a>.
-Generated on: 2014-09-09 19:14 UTC.
+Generated on: 2014-10-08 22:22 UTC.
 Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
 
 </div>
diff --git a/tutorial/generateds_tutorial.txt b/tutorial/generateds_tutorial.txt
index 46348ce..7f91fd9 100644
--- a/tutorial/generateds_tutorial.txt
+++ b/tutorial/generateds_tutorial.txt
@@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial
 
 .. version
 
-:revision: 2.13b
+:revision: 2.14a
 
 .. version
 
diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip
index 157eecae050a3a0201ce0ca0984aaeb93fe97c59..8a4d0465c6f1bb77ab1c106245753ca94932221a 100644
GIT binary patch
delta 11063
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

delta 11043
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

-- 
GitLab