From 1d249917a12b7e98bb44fb1d4974c1450ebc3136 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Thu, 27 Jul 2023 16:04:07 +0100 Subject: [PATCH 01/20] modified the element_to_dict to get a better dictionary representation --- src/modelspec/utils.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 7f0aabca..82007197 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -94,16 +94,21 @@ def element_to_dict(element): if attrs: result.update(attrs) + children_by_tag = {} for child_element in element: - child_key = child_element.tag + child_key = child_element.tag + "s" child_value = element_to_dict(child_element) - if child_key in result: - if not isinstance(result[child_key], list): - result[child_key] = [result[child_key]] - result[child_key].append(child_value) - else: + # Check if the child element has an 'id' attribute + if "id" in child_element.attrib: + # If the child element has an 'id', add it to the result dictionary directly result[child_key] = child_value + else: + # If the child element does not have an 'id', represent it as a list + children_by_tag.setdefault(child_key, []).append(child_value) + + # Append the lists to the result dictionary + result.update(children_by_tag) return result From 40ad91d0fc560c3ebe95712c2151cb9f58f6ee0f Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sat, 29 Jul 2023 22:26:21 +0100 Subject: [PATCH 02/20] generated xml --- examples/neuroml2/TestNeuroML.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index 54ee04dc..b0d47ad9 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,5 +1,6 @@ - + From 6dd377c7d145f02dcdeaa456abda992388402cd4 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sat, 29 Jul 2023 22:27:45 +0100 Subject: [PATCH 03/20] added definition for other namespace values in the neuroml class definition --- examples/neuroml2/neuroml2_spec.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/examples/neuroml2/neuroml2_spec.py b/examples/neuroml2/neuroml2_spec.py index 045931e9..776c15f2 100644 --- a/examples/neuroml2/neuroml2_spec.py +++ b/examples/neuroml2/neuroml2_spec.py @@ -109,6 +109,15 @@ class neuroml(Base): xmlns: str = field( validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" ) + xmlns_url: str = field( + validator=instance_of(str), default="http://www.w3.org/2001/XMLSchema-instance" + ) + xmlns_loc: str = field( + validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" + ) + xmln_loc_2: str = field( + validator=instance_of(str), default="https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" + ) izhikevich2007Cells: List[izhikevich2007Cell] = field(factory=list) pulseGenerators: List[pulseGenerator] = field(factory=list) @@ -187,3 +196,7 @@ class neuroml(Base): yy = yaml.dump(doc_dict, indent=4, sort_keys=False) print(yy) d.write(yy) + + from modelspec.utils import load_xml + new_neuroml = load_xml('hello_world_neuroml.net.nml') + print(new_neuroml) From 43a5adeabc962fb94f3a68dd3c6aeb0b4da8fda1 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sat, 29 Jul 2023 22:28:31 +0100 Subject: [PATCH 04/20] added namespace support --- src/modelspec/utils.py | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 82007197..4d9cd576 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -72,7 +72,10 @@ def load_xml(filename: str): root = tree.getroot() # Get the root element # Convert the ElementTree object to a dictionary - data = element_to_dict(root) + xml_string = ET.tostring(root).decode().replace('ns0:', '').replace(':ns0', '').strip() + + removed_namespaces = process_xml_namespace(xml_string) + data = element_to_dict(removed_namespaces) removed_id = handle_id(data) converted_to_actual_val = convert_values(removed_id) @@ -96,11 +99,11 @@ def element_to_dict(element): children_by_tag = {} for child_element in element: - child_key = child_element.tag + "s" + child_key = child_element.tag + 's' child_value = element_to_dict(child_element) # Check if the child element has an 'id' attribute - if "id" in child_element.attrib: + if 'id' in child_element.attrib: # If the child element has an 'id', add it to the result dictionary directly result[child_key] = child_value else: @@ -113,6 +116,21 @@ def element_to_dict(element): return result +def process_xml_namespace(xml_string): + # Remove ignored elements from the XML string + ignored_elements = [ + 'xmlns="http://www.neuroml.org/schema/neuroml2"', + 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', + 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"' + ] + for ignored_element in ignored_elements: + xml_string = xml_string.replace(ignored_element, '').strip() + + # Parse the XML string into an ElementTree + root = ET.fromstring(xml_string) + return root + + def handle_id(dictionary): if isinstance(dictionary, dict): if "id" in dictionary: @@ -224,14 +242,22 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - else: + elif not any(hasattr(data, attr_name) for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) + if hasattr(data, "xmlns"): + parent.set("xmlns", data.xmlns) + if hasattr(data, "xmlns_url"): + parent.set("xmlns:xsi", data.xmlns_url) + if hasattr(data, "xmlns_loc"): + parent.set("xsi:schemaLocation", str(data.xmlns_loc + '\n' + data.xmln_loc_2)) + return parent + def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From efb2712b41215d6af5edf5502e26ce47867350e6 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sat, 29 Jul 2023 23:06:35 +0100 Subject: [PATCH 05/20] precommited and added better code description --- examples/neuroml2/neuroml2_spec.py | 6 ++++-- src/modelspec/utils.py | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/neuroml2/neuroml2_spec.py b/examples/neuroml2/neuroml2_spec.py index 776c15f2..81dd2d08 100644 --- a/examples/neuroml2/neuroml2_spec.py +++ b/examples/neuroml2/neuroml2_spec.py @@ -116,7 +116,8 @@ class neuroml(Base): validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" ) xmln_loc_2: str = field( - validator=instance_of(str), default="https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" + validator=instance_of(str), + default="https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd", ) izhikevich2007Cells: List[izhikevich2007Cell] = field(factory=list) @@ -198,5 +199,6 @@ class neuroml(Base): d.write(yy) from modelspec.utils import load_xml - new_neuroml = load_xml('hello_world_neuroml.net.nml') + + new_neuroml = load_xml("hello_world_neuroml.net.nml") print(new_neuroml) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 4d9cd576..ec7008e2 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -72,7 +72,9 @@ def load_xml(filename: str): root = tree.getroot() # Get the root element # Convert the ElementTree object to a dictionary - xml_string = ET.tostring(root).decode().replace('ns0:', '').replace(':ns0', '').strip() + xml_string = ( + ET.tostring(root).decode().replace("ns0:", "").replace(":ns0", "").strip() + ) removed_namespaces = process_xml_namespace(xml_string) data = element_to_dict(removed_namespaces) @@ -99,11 +101,11 @@ def element_to_dict(element): children_by_tag = {} for child_element in element: - child_key = child_element.tag + 's' + child_key = child_element.tag + "s" child_value = element_to_dict(child_element) # Check if the child element has an 'id' attribute - if 'id' in child_element.attrib: + if "id" in child_element.attrib: # If the child element has an 'id', add it to the result dictionary directly result[child_key] = child_value else: @@ -121,10 +123,10 @@ def process_xml_namespace(xml_string): ignored_elements = [ 'xmlns="http://www.neuroml.org/schema/neuroml2"', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', - 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"' + 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"', ] for ignored_element in ignored_elements: - xml_string = xml_string.replace(ignored_element, '').strip() + xml_string = xml_string.replace(ignored_element, "").strip() # Parse the XML string into an ElementTree root = ET.fromstring(xml_string) @@ -242,7 +244,10 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - elif not any(hasattr(data, attr_name) for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]): + elif not any( + hasattr(data, attr_name) + for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"] + ): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) @@ -252,12 +257,11 @@ def build_xml_element(data, parent=None): if hasattr(data, "xmlns_url"): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + '\n' + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) return parent - def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From b7ce03b449ff0a8c057683ee8ff7e0bafadae7fb Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sat, 29 Jul 2023 23:12:43 +0100 Subject: [PATCH 06/20] added better code description --- src/modelspec/utils.py | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index ec7008e2..d5428742 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -71,14 +71,20 @@ def load_xml(filename: str): tree = ET.parse(infile) # Parse the XML file into an ElementTree object root = tree.getroot() # Get the root element - # Convert the ElementTree object to a dictionary - xml_string = ( - ET.tostring(root).decode().replace("ns0:", "").replace(":ns0", "").strip() - ) + # Converts the loaded xml into a string and removes unwanted string values ':ns0' and 'ns0:' + # They prevent the xml from loading correctly + xml_string = ET.tostring(root).decode().replace('ns0:', '').replace(':ns0', '').strip() + # Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion removed_namespaces = process_xml_namespace(xml_string) + + # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict data = element_to_dict(removed_namespaces) + + # Removes every key having 'id' and replaces it with it's value removed_id = handle_id(data) + + # Values are returned as strings after conversion, this corrects them to their actual values converted_to_actual_val = convert_values(removed_id) return convert_values(converted_to_actual_val) @@ -101,11 +107,11 @@ def element_to_dict(element): children_by_tag = {} for child_element in element: - child_key = child_element.tag + "s" + child_key = child_element.tag + 's' child_value = element_to_dict(child_element) # Check if the child element has an 'id' attribute - if "id" in child_element.attrib: + if 'id' in child_element.attrib: # If the child element has an 'id', add it to the result dictionary directly result[child_key] = child_value else: @@ -123,10 +129,12 @@ def process_xml_namespace(xml_string): ignored_elements = [ 'xmlns="http://www.neuroml.org/schema/neuroml2"', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', - 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"', + 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"' ] + + # Loops through the xml string and removes every instance of the elements in the list named ignored_elements for ignored_element in ignored_elements: - xml_string = xml_string.replace(ignored_element, "").strip() + xml_string = xml_string.replace(ignored_element, '').strip() # Parse the XML string into an ElementTree root = ET.fromstring(xml_string) @@ -231,6 +239,8 @@ def build_xml_element(data, parent=None): Returns: Parent """ + + # If a parent name isn't given, it extracts the name from the class and use that instead if parent is None: parent = ET.Element(data.__class__.__name__) @@ -244,24 +254,23 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - elif not any( - hasattr(data, attr_name) - for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"] - ): + elif not any(hasattr(data, attr_name) for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) - + + # This defines the various namespaces and schemaLocation of the generated xml if hasattr(data, "xmlns"): parent.set("xmlns", data.xmlns) if hasattr(data, "xmlns_url"): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc + '\n' + data.xmln_loc_2)) return parent + def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From 814a658623cc990c3e00439ce9aec34b4b35c0a6 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sun, 30 Jul 2023 10:30:49 +0100 Subject: [PATCH 07/20] modified the name space check pattern to catch any pattern that arrises --- src/modelspec/base_types.py | 1 - src/modelspec/utils.py | 35 +++++++++++++++++++++++------------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/modelspec/base_types.py b/src/modelspec/base_types.py index 7bb3f6a6..431f34b1 100644 --- a/src/modelspec/base_types.py +++ b/src/modelspec/base_types.py @@ -125,7 +125,6 @@ def to_xml(self) -> str: ) from modelspec.utils import build_xml_element - # root = ET.Element("modelspec") root = build_xml_element(self) xml_string = ET.tostring( diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index d5428742..1bd6fc45 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -67,18 +67,25 @@ def load_xml(filename: str): Args: filename: The name of the XML file to load. """ + import re + with open(filename, "rb") as infile: tree = ET.parse(infile) # Parse the XML file into an ElementTree object root = tree.getroot() # Get the root element - # Converts the loaded xml into a string and removes unwanted string values ':ns0' and 'ns0:' + # This defines regular expressions to match the namespace patterns to be removed + ns_prefix_pattern = r"(ns\d+:|:ns\d+)" + + # Converts the loaded xml into a string and removes unwanted string values ':ns0' to :ns∞ and 'ns0:' to ns∞: # They prevent the xml from loading correctly - xml_string = ET.tostring(root).decode().replace('ns0:', '').replace(':ns0', '').strip() + xml_string = ET.tostring(root).decode() + cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip() # Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion - removed_namespaces = process_xml_namespace(xml_string) + # it passes an element tree object to the element_to_dict function + removed_namespaces = process_xml_namespace(cleaned_xml) - # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict + # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict data = element_to_dict(removed_namespaces) # Removes every key having 'id' and replaces it with it's value @@ -107,11 +114,11 @@ def element_to_dict(element): children_by_tag = {} for child_element in element: - child_key = child_element.tag + 's' + child_key = child_element.tag + "s" child_value = element_to_dict(child_element) # Check if the child element has an 'id' attribute - if 'id' in child_element.attrib: + if "id" in child_element.attrib: # If the child element has an 'id', add it to the result dictionary directly result[child_key] = child_value else: @@ -129,12 +136,12 @@ def process_xml_namespace(xml_string): ignored_elements = [ 'xmlns="http://www.neuroml.org/schema/neuroml2"', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', - 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"' + 'xsi:schemaLocation="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd"', ] # Loops through the xml string and removes every instance of the elements in the list named ignored_elements for ignored_element in ignored_elements: - xml_string = xml_string.replace(ignored_element, '').strip() + xml_string = xml_string.replace(ignored_element, "").strip() # Parse the XML string into an ElementTree root = ET.fromstring(xml_string) @@ -254,23 +261,27 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - elif not any(hasattr(data, attr_name) for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]): + + # Filters name space and schemaLoacation attributes, only allows non name space attributes to added as attributes + elif not any( + hasattr(data, attr_name) + for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"] + ): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) - + # This defines the various namespaces and schemaLocation of the generated xml if hasattr(data, "xmlns"): parent.set("xmlns", data.xmlns) if hasattr(data, "xmlns_url"): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + '\n' + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) return parent - def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From f4ff85cb135f2ae07859345238b2f550229c31f4 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sun, 30 Jul 2023 13:14:37 +0100 Subject: [PATCH 08/20] generated xml almost perfect --- examples/neuroml2/TestNeuroML.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index b0d47ad9..35c43e17 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,10 +1,10 @@ - - +https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" id="TestNeuroML"> + + - + From 53719392f9014291d7746a56fc19170bf971a84f Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sun, 30 Jul 2023 13:16:04 +0100 Subject: [PATCH 09/20] modified the bulid xml element function to produce an almost perfect representation of the neuroml definition --- src/modelspec/utils.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 1bd6fc45..c76b16a3 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -247,13 +247,17 @@ def build_xml_element(data, parent=None): Parent """ - # If a parent name isn't given, it extracts the name from the class and use that instead if parent is None: parent = ET.Element(data.__class__.__name__) attrs = attr.fields(data.__class__) + id_attribute_value = ( + None # Store id attribute value to be set after other attributes + ) for aattr in attrs: - if isinstance(aattr.default, attr.Factory): + if aattr.name == "id": + id_attribute_value = data.__getattribute__(aattr.name) + elif isinstance(aattr.default, attr.Factory): children = data.__getattribute__(aattr.name) if not isinstance(children, (list, tuple)): children = [children] @@ -279,6 +283,10 @@ def build_xml_element(data, parent=None): if hasattr(data, "xmlns_loc"): parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) + # Set the id attribute after processing all other attributes + if id_attribute_value is not None: + parent.set("id", str(id_attribute_value)) + return parent From ed0c66ee3f7d9cb60a163b6c9ecd651c83f963d4 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sun, 30 Jul 2023 17:48:49 +0100 Subject: [PATCH 10/20] extended new namespace support handling to from_xml and from_xml_file methods --- src/modelspec/base_types.py | 63 ++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/modelspec/base_types.py b/src/modelspec/base_types.py index 431f34b1..4ca884aa 100644 --- a/src/modelspec/base_types.py +++ b/src/modelspec/base_types.py @@ -169,11 +169,37 @@ def from_bson(cls, bson_str: str) -> "Base": @classmethod def from_xml(cls, xml_str: str) -> "Base": """Instantiate a Base object from an XML string""" - from modelspec.utils import element_to_dict, handle_id, convert_values + from modelspec.utils import ( + element_to_dict, + handle_id, + convert_values, + process_xml_namespace, + ) + import re + + # When the to_xml() method is used it messes up the string therefore, + # it is necessary to convert it into an elementree object the decode into a string. + xml_string_a = ET.fromstring(xml_str) + xml_string_b = ET.tostring(xml_string_a).decode() + + # while trying to obtain a useable xml structure, using the conversion above it acquires + # some unusual string element that sometimes can be incremental from either :ns0 to :nsX or ns0: to nsX:. + # Using the regex expression pattern catches it in any form and removes it from the xml string structure. + ns_prefix_pattern = r"(ns\d+:|:ns\d+)" + cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string_b).strip() - root = ET.fromstring(xml_str) - data_dict = element_to_dict(root) + # For the xml to be useable in modelspec unnecessary string elements which only serve as asthetics for the xml must + # be removed when converting to a dict, the process_xml_namespaes function does just that. + removed_namespaces = process_xml_namespace(cleaned_xml) + + # process_xml_namespace function returns an elementtree object which can be directly worked upon by the element_to_dict + # function, this returns a python dictionary + data_dict = element_to_dict(removed_namespaces) + + # This strips every instance of 'id' from the resulting dictionary structure removed_id = handle_id(data_dict) + + # XML conversions do not returns exact values, instead all values are returned as a string, this reassigns their actual values converted_to_actual_val = convert_values(removed_id) return cls.from_dict(converted_to_actual_val) @@ -376,14 +402,37 @@ def from_xml_file(cls, filename: str) -> "Base": Returns: A modelspec Base for this XML. """ - from modelspec.utils import element_to_dict, handle_id, convert_values + from modelspec.utils import ( + element_to_dict, + handle_id, + convert_values, + process_xml_namespace, + ) + import re with open(filename) as infile: - tree = ET.parse(infile) - root = tree.getroot() + tree = ET.parse(infile) # Parse the XML file into an ElementTree object + root = tree.getroot() # Get the root element + + # This defines regular expressions to match the namespace patterns to be removed + ns_prefix_pattern = r"(ns\d+:|:ns\d+)" + + # Converts the loaded xml into a string and removes unwanted string values ':ns0' to :ns∞ and 'ns0:' to ns∞: + # They prevent the xml from loading correctly + xml_string = ET.tostring(root).decode() + cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip() - data_dict = element_to_dict(root) + # Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion + # it passes an element tree object to the element_to_dict function + removed_namespaces = process_xml_namespace(cleaned_xml) + + # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict + data_dict = element_to_dict(removed_namespaces) + + # Removes every key having 'id' and replaces it with it's value removed_id = handle_id(data_dict) + + # Values are returned as strings after conversion, this corrects them to their actual values converted_to_actual_val = convert_values(removed_id) return cls.from_dict(converted_to_actual_val) From 1ee113c4314446c4ce3bec51a7b24c4649cc6f7b Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Sun, 30 Jul 2023 17:56:30 +0100 Subject: [PATCH 11/20] hotfix --- src/modelspec/utils.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index c76b16a3..bd840bda 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -251,11 +251,9 @@ def build_xml_element(data, parent=None): parent = ET.Element(data.__class__.__name__) attrs = attr.fields(data.__class__) - id_attribute_value = ( - None # Store id attribute value to be set after other attributes - ) + id_attribute_value = None # Store id attribute value to be set after other attributes for aattr in attrs: - if aattr.name == "id": + if aattr.name == 'id': id_attribute_value = data.__getattribute__(aattr.name) elif isinstance(aattr.default, attr.Factory): children = data.__getattribute__(aattr.name) @@ -265,7 +263,7 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - + # Filters name space and schemaLoacation attributes, only allows non name space attributes to added as attributes elif not any( hasattr(data, attr_name) @@ -274,14 +272,14 @@ def build_xml_element(data, parent=None): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) - + # This defines the various namespaces and schemaLocation of the generated xml if hasattr(data, "xmlns"): parent.set("xmlns", data.xmlns) if hasattr(data, "xmlns_url"): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc + " " + data.xmln_loc_2)) # Set the id attribute after processing all other attributes if id_attribute_value is not None: @@ -289,7 +287,6 @@ def build_xml_element(data, parent=None): return parent - def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From 4a669ee80d7901957172c4858bcd7b1f0a6fb140 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 07:22:35 +0100 Subject: [PATCH 12/20] generated almost perfect xml --- examples/neuroml2/TestNeuroML.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index 35c43e17..70586cf6 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,10 +1,9 @@ - - - + + + - + From 2ba29f67fad0b781a8c4d07ff889bd7edf582475 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 07:24:10 +0100 Subject: [PATCH 13/20] Made changes in the element_to_dict function and changed function names to be more descriptive --- src/modelspec/base_types.py | 30 +++++++++++----------- src/modelspec/utils.py | 51 +++++++++++++++---------------------- 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/modelspec/base_types.py b/src/modelspec/base_types.py index 4ca884aa..f4a81a9d 100644 --- a/src/modelspec/base_types.py +++ b/src/modelspec/base_types.py @@ -170,15 +170,15 @@ def from_bson(cls, bson_str: str) -> "Base": def from_xml(cls, xml_str: str) -> "Base": """Instantiate a Base object from an XML string""" from modelspec.utils import ( - element_to_dict, - handle_id, - convert_values, + elementtree_element_to_dict, + handle_xml_dict_id, + convert_xml_dict_values, process_xml_namespace, ) import re # When the to_xml() method is used it messes up the string therefore, - # it is necessary to convert it into an elementree object the decode into a string. + # it is necessary to convert it into an elementree object then decode into a string. xml_string_a = ET.fromstring(xml_str) xml_string_b = ET.tostring(xml_string_a).decode() @@ -192,15 +192,15 @@ def from_xml(cls, xml_str: str) -> "Base": # be removed when converting to a dict, the process_xml_namespaes function does just that. removed_namespaces = process_xml_namespace(cleaned_xml) - # process_xml_namespace function returns an elementtree object which can be directly worked upon by the element_to_dict + # process_xml_namespace function returns an elementtree object which can be directly worked upon by the elementtree_element_to_dict # function, this returns a python dictionary - data_dict = element_to_dict(removed_namespaces) + data_dict = elementtree_element_to_dict(removed_namespaces) # This strips every instance of 'id' from the resulting dictionary structure - removed_id = handle_id(data_dict) + removed_id = handle_xml_dict_id(data_dict) # XML conversions do not returns exact values, instead all values are returned as a string, this reassigns their actual values - converted_to_actual_val = convert_values(removed_id) + converted_to_actual_val = convert_xml_dict_values(removed_id) return cls.from_dict(converted_to_actual_val) @@ -403,9 +403,9 @@ def from_xml_file(cls, filename: str) -> "Base": A modelspec Base for this XML. """ from modelspec.utils import ( - element_to_dict, - handle_id, - convert_values, + elementtree_element_to_dict, + handle_xml_dict_id, + convert_xml_dict_values, process_xml_namespace, ) import re @@ -423,17 +423,17 @@ def from_xml_file(cls, filename: str) -> "Base": cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip() # Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion - # it passes an element tree object to the element_to_dict function + # it passes an element tree object to the elementtree_element_to_dict function removed_namespaces = process_xml_namespace(cleaned_xml) # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict - data_dict = element_to_dict(removed_namespaces) + data_dict = elementtree_element_to_dict(removed_namespaces) # Removes every key having 'id' and replaces it with it's value - removed_id = handle_id(data_dict) + removed_id = handle_xml_dict_id(data_dict) # Values are returned as strings after conversion, this corrects them to their actual values - converted_to_actual_val = convert_values(removed_id) + converted_to_actual_val = convert_xml_dict_values(removed_id) return cls.from_dict(converted_to_actual_val) def get_child(self, id: str, type_: str) -> Any: diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index bd840bda..3d684941 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -82,22 +82,22 @@ def load_xml(filename: str): cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip() # Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion - # it passes an element tree object to the element_to_dict function + # it passes an element tree object to the elementtree_element_to_dict function removed_namespaces = process_xml_namespace(cleaned_xml) # Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict - data = element_to_dict(removed_namespaces) + data = elementtree_element_to_dict(removed_namespaces) # Removes every key having 'id' and replaces it with it's value - removed_id = handle_id(data) + removed_id = handle_xml_dict_id(data) # Values are returned as strings after conversion, this corrects them to their actual values - converted_to_actual_val = convert_values(removed_id) + converted_to_actual_val = convert_xml_dict_values(removed_id) - return convert_values(converted_to_actual_val) + return convert_xml_dict_values(converted_to_actual_val) -def element_to_dict(element): +def elementtree_element_to_dict(element): """ This convert an ElementTree element to a dictionary. @@ -115,7 +115,7 @@ def element_to_dict(element): children_by_tag = {} for child_element in element: child_key = child_element.tag + "s" - child_value = element_to_dict(child_element) + child_value = elementtree_element_to_dict(child_element) # Check if the child element has an 'id' attribute if "id" in child_element.attrib: @@ -148,21 +148,21 @@ def process_xml_namespace(xml_string): return root -def handle_id(dictionary): +def handle_xml_dict_id(dictionary): if isinstance(dictionary, dict): if "id" in dictionary: nested_dict = {dictionary["id"]: dictionary.copy()} del nested_dict[dictionary["id"]]["id"] - return {k: handle_id(v) for k, v in nested_dict.items()} + return {k: handle_xml_dict_id(v) for k, v in nested_dict.items()} else: - return {k: handle_id(v) for k, v in dictionary.items()} + return {k: handle_xml_dict_id(v) for k, v in dictionary.items()} elif isinstance(dictionary, list): - return [handle_id(item) for item in dictionary] + return [handle_xml_dict_id(item) for item in dictionary] else: return dictionary -def convert_values(value): +def convert_xml_dict_values(value): """ This recursively converts values to their actual types. @@ -186,9 +186,9 @@ def convert_values(value): elif value.lower() == "none": return None elif isinstance(value, dict): - return {key: convert_values(val) for key, val in value.items()} + return {key: convert_xml_dict_values(val) for key, val in value.items()} elif isinstance(value, list): - return [convert_values(item) for item in value] + return [convert_xml_dict_values(item) for item in value] return value @@ -246,16 +246,12 @@ def build_xml_element(data, parent=None): Returns: Parent """ - if parent is None: parent = ET.Element(data.__class__.__name__) attrs = attr.fields(data.__class__) - id_attribute_value = None # Store id attribute value to be set after other attributes for aattr in attrs: - if aattr.name == 'id': - id_attribute_value = data.__getattribute__(aattr.name) - elif isinstance(aattr.default, attr.Factory): + if isinstance(aattr.default, attr.Factory): children = data.__getattribute__(aattr.name) if not isinstance(children, (list, tuple)): children = [children] @@ -263,16 +259,13 @@ def build_xml_element(data, parent=None): for child in children: child_element = build_xml_element(child) parent.append(child_element) - - # Filters name space and schemaLoacation attributes, only allows non name space attributes to added as attributes - elif not any( - hasattr(data, attr_name) - for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"] - ): + + # Filters name space and schemaLoacation attributes, only allows non name space attributes to be added as attributes + elif aattr.name not in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]: attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) - + # This defines the various namespaces and schemaLocation of the generated xml if hasattr(data, "xmlns"): parent.set("xmlns", data.xmlns) @@ -280,13 +273,9 @@ def build_xml_element(data, parent=None): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): parent.set("xsi:schemaLocation", str(data.xmlns_loc + " " + data.xmln_loc_2)) - - # Set the id attribute after processing all other attributes - if id_attribute_value is not None: - parent.set("id", str(id_attribute_value)) - return parent + def ascii_encode_dict(data): ascii_encode = ( lambda x: x.encode("ascii") From 99b30ba7b6d0566a85857990462b4f7af0b71a56 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 19:22:18 +0100 Subject: [PATCH 14/20] hotfix --- src/modelspec/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 3d684941..5f85d190 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -92,9 +92,9 @@ def load_xml(filename: str): removed_id = handle_xml_dict_id(data) # Values are returned as strings after conversion, this corrects them to their actual values - converted_to_actual_val = convert_xml_dict_values(removed_id) + # converted_to_actual_val = convert_xml_dict_values(removed_id) - return convert_xml_dict_values(converted_to_actual_val) + return convert_xml_dict_values(removed_id) def elementtree_element_to_dict(element): From b7903528c8bb857251abd553ba956cc5f02e5e84 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 19:25:49 +0100 Subject: [PATCH 15/20] added new line in place of name space to the xml:schmaLocation attribute setter --- src/modelspec/utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index 5f85d190..faead937 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -92,8 +92,6 @@ def load_xml(filename: str): removed_id = handle_xml_dict_id(data) # Values are returned as strings after conversion, this corrects them to their actual values - # converted_to_actual_val = convert_xml_dict_values(removed_id) - return convert_xml_dict_values(removed_id) @@ -272,7 +270,7 @@ def build_xml_element(data, parent=None): if hasattr(data, "xmlns_url"): parent.set("xmlns:xsi", data.xmlns_url) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + " " + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) return parent From f1b9349cc7da53cd2a97034ecc6a0c0778238465 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 19:29:01 +0100 Subject: [PATCH 16/20] generated almost perfect xml --- examples/neuroml2/TestNeuroML.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index 70586cf6..4a827640 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,5 +1,6 @@ - + From 5178aa89f48ae0da4b41180a65d662f8c936c3aa Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Mon, 31 Jul 2023 20:17:41 +0100 Subject: [PATCH 17/20] made the build_element_element function more dynamic when handling default values that are not factory but string in nature --- src/modelspec/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index faead937..ebeb7ff0 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -259,7 +259,7 @@ def build_xml_element(data, parent=None): parent.append(child_element) # Filters name space and schemaLoacation attributes, only allows non name space attributes to be added as attributes - elif aattr.name not in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]: + elif not isinstance(aattr.default, str): attribute_name = aattr.name attribute_value = data.__getattribute__(aattr.name) parent.set(attribute_name, str(attribute_value)) From cc09993ed0a70f6ea80f70aaa1a88e218ad5622d Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Tue, 1 Aug 2023 18:46:58 +0100 Subject: [PATCH 18/20] added changes to the schema location defination removed xml_loc2 --- examples/neuroml2/neuroml2_spec.py | 9 +++------ src/modelspec/utils.py | 6 +++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/examples/neuroml2/neuroml2_spec.py b/examples/neuroml2/neuroml2_spec.py index 81dd2d08..0b608070 100644 --- a/examples/neuroml2/neuroml2_spec.py +++ b/examples/neuroml2/neuroml2_spec.py @@ -109,16 +109,13 @@ class neuroml(Base): xmlns: str = field( validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" ) - xmlns_url: str = field( + xmlns_xsi: str = field( validator=instance_of(str), default="http://www.w3.org/2001/XMLSchema-instance" ) xmlns_loc: str = field( - validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" - ) - xmln_loc_2: str = field( - validator=instance_of(str), - default="https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd", + validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" ) + izhikevich2007Cells: List[izhikevich2007Cell] = field(factory=list) pulseGenerators: List[pulseGenerator] = field(factory=list) diff --git a/src/modelspec/utils.py b/src/modelspec/utils.py index ebeb7ff0..16844cb1 100644 --- a/src/modelspec/utils.py +++ b/src/modelspec/utils.py @@ -267,10 +267,10 @@ def build_xml_element(data, parent=None): # This defines the various namespaces and schemaLocation of the generated xml if hasattr(data, "xmlns"): parent.set("xmlns", data.xmlns) - if hasattr(data, "xmlns_url"): - parent.set("xmlns:xsi", data.xmlns_url) + if hasattr(data, "xmlns_xsi"): + parent.set("xmlns:xsi", data.xmlns_xsi) if hasattr(data, "xmlns_loc"): - parent.set("xsi:schemaLocation", str(data.xmlns_loc + "\n" + data.xmln_loc_2)) + parent.set("xsi:schemaLocation", str(data.xmlns_loc)) return parent From 954f290bbf05ea8dca35d64006fd9d4160bd57c0 Mon Sep 17 00:00:00 2001 From: mqnifestkelvin Date: Thu, 3 Aug 2023 19:47:28 +0100 Subject: [PATCH 19/20] generated new xml and precommitted --- examples/neuroml2/TestNeuroML.xml | 3 +-- examples/neuroml2/neuroml2_spec.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index 4a827640..d573d7b3 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,6 +1,5 @@ - + diff --git a/examples/neuroml2/neuroml2_spec.py b/examples/neuroml2/neuroml2_spec.py index 0b608070..eccef5b5 100644 --- a/examples/neuroml2/neuroml2_spec.py +++ b/examples/neuroml2/neuroml2_spec.py @@ -113,9 +113,9 @@ class neuroml(Base): validator=instance_of(str), default="http://www.w3.org/2001/XMLSchema-instance" ) xmlns_loc: str = field( - validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd" + validator=instance_of(str), + default="http://www.neuroml.org/schema/neuroml2https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd", ) - izhikevich2007Cells: List[izhikevich2007Cell] = field(factory=list) pulseGenerators: List[pulseGenerator] = field(factory=list) From c47685fed73540168c449f3a86f0bff9eea2dc68 Mon Sep 17 00:00:00 2001 From: pgleeson Date: Tue, 15 Aug 2023 15:38:47 +0100 Subject: [PATCH 20/20] Remove space in xsi:schemaLocation; more docs --- examples/neuroml2/NeuroML2.md | 20 ++++++++++++++++--- examples/neuroml2/NeuroML2.rst | 20 ++++++++++--------- examples/neuroml2/NeuroML2.specification.json | 14 ++++++++++--- examples/neuroml2/NeuroML2.specification.yaml | 12 ++++++++--- examples/neuroml2/TestNeuroML.xml | 2 +- examples/neuroml2/neuroml2_spec.py | 9 +++++++-- 6 files changed, 56 insertions(+), 21 deletions(-) diff --git a/examples/neuroml2/NeuroML2.md b/examples/neuroml2/NeuroML2.md index aabfc643..405be412 100644 --- a/examples/neuroml2/NeuroML2.md +++ b/examples/neuroml2/NeuroML2.md @@ -13,7 +13,21 @@ Some description... xmlns str - Schema for NeuroML 2, usually http://www.neuroml.org/schema/neuroml2 + Default namespace for the NeuroML file, usually http://www.neuroml.org/schema/neuroml2 + + + + + xmlns_xsi + str + Namespace for XMLSchema-instance + + + + + xmlns_loc + str + Specifies location of the main namespace @@ -24,14 +38,14 @@ Some description... izhikevich2007Cells izhikevich2007Cell - + The izhikevich2007Cells pulseGenerators pulseGenerator - + The pulse current generators diff --git a/examples/neuroml2/NeuroML2.rst b/examples/neuroml2/NeuroML2.rst index ee22286c..2a812b47 100644 --- a/examples/neuroml2/NeuroML2.rst +++ b/examples/neuroml2/NeuroML2.rst @@ -5,22 +5,24 @@ Some description... **Allowed parameters** -=============== =========== ==================================================================== +=============== =========== ====================================================================================== Allowed field Data Type Description -=============== =========== ==================================================================== +=============== =========== ====================================================================================== **id** str The id of the NeuroML 2 document -**xmlns** str Schema for NeuroML 2, usually http://www.neuroml.org/schema/neuroml2 -=============== =========== ==================================================================== +**xmlns** str Default namespace for the NeuroML file, usually http://www.neuroml.org/schema/neuroml2 +**xmlns_xsi** str Namespace for XMLSchema-instance +**xmlns_loc** str Specifies location of the main namespace +=============== =========== ====================================================================================== **Allowed children** -======================= ============================================ ==================== +======================= ============================================ ============================ Allowed child Data Type Description -======================= ============================================ ==================== -**izhikevich2007Cells** `izhikevich2007Cell <#izhikevich2007cell>`__ -**pulseGenerators** `pulseGenerator <#pulsegenerator>`__ +======================= ============================================ ============================ +**izhikevich2007Cells** `izhikevich2007Cell <#izhikevich2007cell>`__ The izhikevich2007Cells +**pulseGenerators** `pulseGenerator <#pulsegenerator>`__ The pulse current generators **networks** `network <#network>`__ The networks present -======================= ============================================ ==================== +======================= ============================================ ============================ ================== izhikevich2007Cell diff --git a/examples/neuroml2/NeuroML2.specification.json b/examples/neuroml2/NeuroML2.specification.json index fe211575..8e39c0eb 100644 --- a/examples/neuroml2/NeuroML2.specification.json +++ b/examples/neuroml2/NeuroML2.specification.json @@ -8,17 +8,25 @@ }, "xmlns": { "type": "str", - "description": "Schema for NeuroML 2, usually http://www.neuroml.org/schema/neuroml2" + "description": "Default namespace for the NeuroML file, usually http://www.neuroml.org/schema/neuroml2" + }, + "xmlns_xsi": { + "type": "str", + "description": "Namespace for XMLSchema-instance" + }, + "xmlns_loc": { + "type": "str", + "description": "Specifies location of the main namespace" } }, "allowed_children": { "izhikevich2007Cells": { "type": "izhikevich2007Cell", - "description": "" + "description": "The izhikevich2007Cells" }, "pulseGenerators": { "type": "pulseGenerator", - "description": "" + "description": "The pulse current generators" }, "networks": { "type": "network", diff --git a/examples/neuroml2/NeuroML2.specification.yaml b/examples/neuroml2/NeuroML2.specification.yaml index 0d4bb12a..df89cb5b 100644 --- a/examples/neuroml2/NeuroML2.specification.yaml +++ b/examples/neuroml2/NeuroML2.specification.yaml @@ -6,14 +6,20 @@ neuroml: description: The id of the NeuroML 2 document xmlns: type: str - description: Schema for NeuroML 2, usually http://www.neuroml.org/schema/neuroml2 + description: Default namespace for the NeuroML file, usually http://www.neuroml.org/schema/neuroml2 + xmlns_xsi: + type: str + description: Namespace for XMLSchema-instance + xmlns_loc: + type: str + description: Specifies location of the main namespace allowed_children: izhikevich2007Cells: type: izhikevich2007Cell - description: '' + description: The izhikevich2007Cells pulseGenerators: type: pulseGenerator - description: '' + description: The pulse current generators networks: type: network description: The networks present diff --git a/examples/neuroml2/TestNeuroML.xml b/examples/neuroml2/TestNeuroML.xml index d573d7b3..70586cf6 100644 --- a/examples/neuroml2/TestNeuroML.xml +++ b/examples/neuroml2/TestNeuroML.xml @@ -1,5 +1,5 @@ - + diff --git a/examples/neuroml2/neuroml2_spec.py b/examples/neuroml2/neuroml2_spec.py index eccef5b5..6b07fda5 100644 --- a/examples/neuroml2/neuroml2_spec.py +++ b/examples/neuroml2/neuroml2_spec.py @@ -101,11 +101,16 @@ class neuroml(Base): Args: id: The id of the NeuroML 2 document - xmlns: Schema for NeuroML 2, usually http://www.neuroml.org/schema/neuroml2 + xmlns: Default namespace for the NeuroML file, usually http://www.neuroml.org/schema/neuroml2 + xmlns_xsi: Namespace for XMLSchema-instance + xmlns_loc: Specifies location of the main namespace + izhikevich2007Cells: The izhikevich2007Cells + pulseGenerators: The pulse current generators networks: The networks present """ id: str = field(validator=instance_of(str)) + xmlns: str = field( validator=instance_of(str), default="http://www.neuroml.org/schema/neuroml2" ) @@ -114,7 +119,7 @@ class neuroml(Base): ) xmlns_loc: str = field( validator=instance_of(str), - default="http://www.neuroml.org/schema/neuroml2https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd", + default="http://www.neuroml.org/schema/neuroml2 https://raw.github.com/NeuroML/NeuroML2/development/Schemas/NeuroML2/NeuroML_v2.3.xsd", ) izhikevich2007Cells: List[izhikevich2007Cell] = field(factory=list)