diff --git a/MANIFEST.in b/MANIFEST.in index 849b1685468fd814d603be0d5a65b16e79c1e656..99fe7ea79096fc51b2b423827da2ce0d5072df90 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include README LICENSE MANIFEST.in +include README.rst LICENSE MANIFEST.in include setup.py include generateDS.py include generateds_config.py diff --git a/README.rst b/README.rst index c9004316fe791162356fe3edc2547817b2888998..89eef6de68fe146867ac39c9553448f50f0ee0c0 100644 --- a/README.rst +++ b/README.rst @@ -141,6 +141,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Change history -------------- +Version 2.29.6 (01/22/2017) + +- Fix to generation of namespace prefix in export methods. With + this fix, process_includes.py collects information about which + xs:element and xs:complexType definitions are in which target + namespaces. Then generateDS.py uses that dictionary to generate + export methods that produce the namespace prefix. Thanks to Rob + Calvert for identifying this problem and for helping me to + understand it. + +Version 2.29.5 (01/17/2017) + +- Fix to prevent infinite recursion that happens when a simple type + is defined whose name is the same as it's restriction base type + except for the namespace prefix. Thanks to Nicolas de Saint Jorre + for reporting this problem and for providing a schema that + reproduces it. + Version 2.29.4 (12/14/2017) - Fix for exporting the child of an element, when that child is diff --git a/generateDS.html b/generateDS.html index 0184ba9eed0f4d87f068aa4e42ced4e6adb25173..a94408a5fc002dc55fe5c233c7b66737e9400f90 100644 --- a/generateDS.html +++ b/generateDS.html @@ -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.29.4</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.6</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">December 14, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">January 26, 2018</td> </tr> </tbody> </table> @@ -3380,7 +3380,7 @@ following among others:</p> <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateDS.txt">View document source</a>. -Generated on: 2017-12-14 22:46 UTC. +Generated on: 2018-01-27 00:06 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 bfe6ae7da92c07d9a948c80f5287e0e36ced437a..b29c78dcb5590ed455cadd827bce7ec730a2b028 100755 --- a/generateDS.py +++ b/generateDS.py @@ -229,7 +229,7 @@ logging.disable(logging.INFO) # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.4' +VERSION = '2.29.6' ##VERSION## BaseStrTypes = six.string_types @@ -261,6 +261,7 @@ NoNameSpaceDefs = False CleanupNameList = [(re.compile('[-:.]'), '_')] NamespacesDict = {} +SchemaNamespaceDict = {} prefixToNamespaceMap = {} MappingTypes = {} Targetnamespace = "" @@ -2810,6 +2811,9 @@ def generateExportFn(wrt, prefix, element, namespace, nameSpacesDef): childCount = countChildren(element, 0) name = element.getName() base = element.getBase() + ns_prefix = SchemaNamespaceDict.get(name) + if ns_prefix is not None: + namespace = ns_prefix + ':' wrt(" def export(self, outfile, level, namespace_='%s', " "name_='%s', namespacedef_='%s', pretty_print=True):\n" % (namespace, name, nameSpacesDef)) @@ -4541,16 +4545,19 @@ def processValidatorBodyRestrictions( if base1 is not None: if ":" in base1: base1 = base1.split(":")[1] - st1 = find_simple_type_def(tree, base1, None, None, ns, base) - if st1 is not None: - restrictions1 = st1.xpath( - "./xs:restriction", - namespaces=ns, n=stName, b=base) - if restrictions1: - s2 = processValidatorBodyRestrictions( - tree, '', restrictions1, st1, ns, stName, - base1, patterns1) - s1 += s2 + # Check special case: simpletype that restricts xs:simpletype. + # Prevent infinite recursion. + if st.get('name') != base1: + st1 = find_simple_type_def(tree, base1, None, None, ns, base) + if st1 is not None: + restrictions1 = st1.xpath( + "./xs:restriction", + namespaces=ns, n=stName, b=base) + if restrictions1: + s2 = processValidatorBodyRestrictions( + tree, '', restrictions1, st1, ns, stName, + base1, patterns1) + s1 += s2 return s1 # end processValidatorBodyRestrictions @@ -6847,7 +6854,8 @@ def parseAndGenerate( global DelayedElements, DelayedElements_subclass, \ AlreadyGenerated, SaxDelayedElements, \ AlreadyGenerated_subclass, UserMethodsPath, UserMethodsModule, \ - SchemaLxmlTree, ModuleSuffix, UseSourceFileAsModuleName + SchemaLxmlTree, ModuleSuffix, UseSourceFileAsModuleName, \ + SchemaNamespaceDict DelayedElements = set() DelayedElements_subclass = set() AlreadyGenerated = set() @@ -6874,7 +6882,7 @@ def parseAndGenerate( outfile = StringIO.StringIO() else: outfile = io.StringIO() - doc = process_includes.process_include_files( + doc, SchemaNamespaceDict = process_includes.process_include_files( infile, outfile, inpath=xschemaFileName, catalogpath=catalogFilename, @@ -6911,7 +6919,7 @@ def parseAndGenerate( outfile = StringIO.StringIO() else: outfile = io.StringIO() - doc = process_includes.process_include_files( + doc, SchemaNamespaceDict = process_includes.process_include_files( infile, outfile, inpath=xschemaFileName, catalogpath=catalogFilename, diff --git a/generateDS.txt b/generateDS.txt index 608888fa407f30f005a6eaf2dcac5d58fcf78309..870ac5ef6c9b3303e2bd89f1e95c10f45fae3be1 100644 --- a/generateDS.txt +++ b/generateDS.txt @@ -12,7 +12,7 @@ generateDS -- Generate Data Structures from XML Schema .. version -:revision: 2.29.4 +:revision: 2.29.6 .. version diff --git a/generateds_gui_notes.html b/generateds_gui_notes.html index 576b4823901a7286063de69e5c341426a248f164..e1920d128b9b6cf0259953cf15ca64c0420f47b1 100644 --- a/generateds_gui_notes.html +++ b/generateds_gui_notes.html @@ -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.29.4</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.6</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">December 14, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">January 26, 2018</td> </tr> </tbody> </table> @@ -401,7 +401,7 @@ $ mv generateds_gui.mo locale/ru/LC_MESSAGES/ <div class="footer"> <hr class="footer" /> <a class="reference external" href="generateds_gui_notes.txt">View document source</a>. -Generated on: 2017-12-14 22:46 UTC. +Generated on: 2018-01-27 00:06 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_gui_notes.txt b/generateds_gui_notes.txt index 59a6d69929b7e2d94a16fcfebe3acfa403bb6eb9..51ed6e1d73694ee9f1c2f660e7f866624e568648 100644 --- a/generateds_gui_notes.txt +++ b/generateds_gui_notes.txt @@ -12,7 +12,7 @@ GenerateDS GUI Notes .. version -:revision: 2.29.4 +:revision: 2.29.6 .. version diff --git a/gui/generateds_gui.py b/gui/generateds_gui.py index 4e13f9014b955ae5e2764adc18f6d5af7df9e1bb..cabaf5b76c909166bdab2f1ac5db7e1996a7cc19 100644 --- a/gui/generateds_gui.py +++ b/gui/generateds_gui.py @@ -41,7 +41,7 @@ from libgenerateDS.gui import generateds_gui_session # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.4' +VERSION = '2.29.6' ##VERSION## diff --git a/librarytemplate_howto.html b/librarytemplate_howto.html index 0dff031ed8cd9ef36ac318baea9fdc1e05c7b222..b225b20b90440b2ae4550d9167499f5cf3501469 100644 --- a/librarytemplate_howto.html +++ b/librarytemplate_howto.html @@ -217,7 +217,7 @@ dkuhlman (at) davekuhlman (dot) org <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.29.4</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.6</td> </tr> </tbody> </table> @@ -226,7 +226,7 @@ dkuhlman (at) davekuhlman (dot) org <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> -<tr class="field"><th class="field-name">date:</th><td class="field-body">December 14, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">January 26, 2018</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: 2017-12-14 22:46 UTC. +Generated on: 2018-01-27 00:06 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 702e57190902bc0b975802f2d3cf5bd4376f78d1..70618b2b5cd5d2f79d29cdd9e831b17b494f1653 100644 --- a/librarytemplate_howto.txt +++ b/librarytemplate_howto.txt @@ -8,7 +8,7 @@ How to package a generateDS.py generated library .. version -:revision: 2.29.4 +:revision: 2.29.6 .. version diff --git a/process_includes.py b/process_includes.py old mode 100644 new mode 100755 index 723639a1b42cb1469423a51b7a341eef80036311..1da1edf08989f1bba86c5e3d170f9e3baa8f8840 --- a/process_includes.py +++ b/process_includes.py @@ -40,7 +40,7 @@ except ImportError: # Do not modify the following VERSION comments. # Used by updateversion.py. ##VERSION## -VERSION = '2.29.4' +VERSION = '2.29.6' ##VERSION## CatalogDict = {} @@ -85,8 +85,8 @@ def process_include_files( 'no_collect_includes': no_collect_includes, 'no_redefine_groups': no_redefine_groups, }) - doc = prep_schema_doc(infile, outfile, inpath, options) - return doc + doc, ns_dict = prep_schema_doc(infile, outfile, inpath, options) + return doc, ns_dict def get_all_root_file_paths( @@ -151,7 +151,6 @@ def get_ref_info(node, params): baseUrl = CatalogBaseUrl if not url: url = node.get('schemaLocation') - if not url: msg = '*** Warning: missing "schemaLocation" attribute in %s\n' % ( params.parent_url, ) @@ -160,10 +159,8 @@ def get_ref_info(node, params): # Uncomment the next lines to help track down missing schemaLocation etc. # print '(resolve_ref) url: %s\n parent-url: %s' % ( # url, params.parent_url, ) - if not baseUrl: baseUrl = params.base_url - if baseUrl and not ( url.startswith('/') or url.startswith('http:') or @@ -173,15 +170,12 @@ def get_ref_info(node, params): else: locn = url schema_name = url - return locn, schema_name def resolve_ref(node, params, options): content = None - locn, schema_name = get_ref_info(node, params) - if locn is not None and not ( locn.startswith('/') or locn.startswith('http:') or @@ -235,25 +229,26 @@ def resolve_ref(node, params, options): return content -def collect_inserts(node, params, inserts, options): +def collect_inserts(node, params, inserts, ns_dict, options): namespace = node.nsmap[node.prefix] roots = [] child_iter1 = node.iterfind('{%s}include' % (namespace, )) child_iter2 = node.iterfind('{%s}import' % (namespace, )) for child in itertools.chain(child_iter1, child_iter2): - aux_roots = collect_inserts_aux(child, params, inserts, options) + aux_roots = collect_inserts_aux( + child, params, inserts, ns_dict, options) roots.extend(aux_roots) - return roots -def collect_inserts_aux(child, params, inserts, options): +def collect_inserts_aux(child, params, inserts, ns_dict, options): roots = [] save_base_url = params.base_url string_content = resolve_ref(child, params, options) if string_content is not None: root = etree.fromstring(string_content, base_url=params.base_url) roots.append(root) + update_ns_dict(root, ns_dict, options) for child1 in root: if not isinstance(child1, etree._Comment): namespace = child1.nsmap[child1.prefix] @@ -263,12 +258,31 @@ def collect_inserts_aux(child, params, inserts, options): comment.tail = '\n' inserts.append(comment) inserts.append(child1) - insert_roots = collect_inserts(root, params, inserts, options) + insert_roots = collect_inserts(root, params, inserts, ns_dict, options) roots.extend(insert_roots) params.base_url = save_base_url return roots +def update_ns_dict(root, ns_dict, options): + """Update the namespace dictionary with the target namespace prefix, + if there is one, for each global xs:element and xs:complexType. + """ + if 'targetNamespace' in root.attrib: + namespace = root.get('targetNamespace') + defs = [nsdef for nsdef in root.nsmap.items() if nsdef[1] == namespace] + if defs: + prefix = defs[0][0] + # Get top level xs:complexType and xs:element elements. + nsmap = {'xs': 'http://www.w3.org/2001/XMLSchema'} + items1 = root.xpath('./xs:complexType', namespaces=nsmap) + items2 = root.xpath('./xs:element', namespaces=nsmap) + names = ([item.get('name') for item in items1] + + [item.get('name') for item in items2]) + for name in names: + ns_dict[name] = prefix + + def get_root_file_paths(node, params, rootPaths, shallow): namespace = node.nsmap[node.prefix] child_iter1 = node.iterfind('{%s}include' % (namespace, )) @@ -311,8 +325,9 @@ def prep_schema_doc(infile, outfile, inpath, options): params.parent_url = infile params.base_url = os.path.split(inpath)[0] inserts = [] + ns_dict = {} if not options.no_collect_includes: - collect_inserts(root1, params, inserts, options) + collect_inserts(root1, params, inserts, ns_dict, options) root2 = copy.copy(root1) clear_includes_and_imports(root2) for insert_node in inserts: @@ -328,7 +343,7 @@ def prep_schema_doc(infile, outfile, inpath, options): doc2.write(outfile) else: outfile.write(etree.tostring(root2).decode('utf-8')) - return doc2 + return doc2, ns_dict def prep_schema(inpath, outpath, options): diff --git a/setup.py b/setup.py index 93eeec3cd2ecd5f131b6121fdb7cffbc67caf0ef..4ea8b3ddec0f0e57e92fea4f8213316f0086d3b9 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.29.4", + version="2.29.6", ##VERSION## author="Dave Kuhlman", author_email="dkuhlman@davekuhlman.org", diff --git a/tutorial/generateds_tutorial.html b/tutorial/generateds_tutorial.html index 40a49cd9a4ec0d54f9b0eeded0145481d474d8e4..e2c7c02cbd078430ed06ada71b0f5ef8455aacbb 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.29.4</td> +<tr class="field"><th class="field-name">revision:</th><td class="field-body">2.29.6</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">December 14, 2017</td> +<tr class="field"><th class="field-name">date:</th><td class="field-body">January 26, 2018</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: 2017-12-14 22:46 UTC. +Generated on: 2018-01-27 00:06 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 ec4b328ac12c7bf91332506a580f60053e9e0223..d2a348432207d6f0848d6d31ca6219ea555410e1 100644 --- a/tutorial/generateds_tutorial.txt +++ b/tutorial/generateds_tutorial.txt @@ -11,7 +11,7 @@ generateDS -- Introduction and Tutorial .. version -:revision: 2.29.4 +:revision: 2.29.6 .. version diff --git a/tutorial/generateds_tutorial.zip b/tutorial/generateds_tutorial.zip index 2df8e3b9633f8cec64f6150fb17446a73cb67f39..d5e3c16766680d98568d9064d6e7d0062f1e22a4 100644 Binary files a/tutorial/generateds_tutorial.zip and b/tutorial/generateds_tutorial.zip differ