From 12e7ed356cdd62277e305012fe2be89a71c6e9f7 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 10 May 2022 16:22:12 +1000 Subject: [PATCH] Fix IDS namespace bug that prevented XML encoding, simplify XML writing, and new to_string() method to decrease dependency on the filesystem --- src/ifcopenshell-python/ifcopenshell/ids.py | 53 +++++++-------------- src/ifcopenshell-python/test/test_ids.py | 9 +++- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/ifcopenshell-python/ifcopenshell/ids.py b/src/ifcopenshell-python/ifcopenshell/ids.py index f4b68ef45c..6134500e5b 100644 --- a/src/ifcopenshell-python/ifcopenshell/ids.py +++ b/src/ifcopenshell-python/ifcopenshell/ids.py @@ -33,6 +33,7 @@ from bcf.v2 import data as bcf from xmlschema import XMLSchema from xmlschema import etree_tostring from xmlschema.validators import identities +from xml.etree import ElementTree as ET cwd = os.path.dirname(os.path.realpath(__file__)) @@ -117,50 +118,28 @@ class ids: ids_dict["specifications"].append({"specification": spec.asdict()}) #TEST! return ids_dict - def to_xml(self, filepath="./", ids_schema=ids_schema): - """Save IDS object as .xml file. + def to_string(self, ids_schema=ids_schema): + """Convert IDS object to XML string - :param filepath: Path for the new file, defaults to "./" + :param ids_schema: XML Schema for an IDS file, defaults to ids_schema object from buildingSMART + :type ids_schema: XMLschema, optional + :return: The contents of the XML data in string form + :rtype: string + """ + ns = {"": "http://standards.buildingsmart.org/IDS"} + return etree_tostring(ids_schema.encode(self.asdict()), namespaces=ns) + + def to_xml(self, filepath="output.xml", ids_schema=ids_schema): + """Writes IDS object to an XML file. + + :param filepath: Path to the file, defaults to "output.xml" :type filepath: str, optional :param ids_schema: XML Schema for an IDS file, defaults to ids_schema object from buildingSMART :type ids_schema: XMLschema, optional :return: Result of the newly created file validation against the schema. :rtype: bool """ - - if filepath.endswith("/"): - filepath = filepath + "IDS" - if not filepath.endswith(".xml"): - filepath = filepath + ".xml" - - ids_dict = self.asdict() - - ids_xml = ids_schema.encode( - ids_dict, - namespaces={ - "": "http://standards.buildingsmart.org/IDS", - "xs": "http://www.w3.org/2001/XMLSchema", - "xsi": "http://www.w3.org/2001/XMLSchema-instance", - "xsi:schemaLocation": "http://standards.buildingsmart.org/IDS/ids_05.xsd", - }, - ) # validation='skip', - - ids_str = etree_tostring( - ids_xml, - namespaces={ - "": "http://standards.buildingsmart.org/IDS", - # 'xs': 'http://www.w3.org/2001/XMLSchema', - # 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', - # 'xsi:schemaLocation': "http://standards.buildingsmart.org/IDS/ids_05.xsd" - }, - ) - - with open(filepath, "w", encoding="utf-8") as f: - f.write('\n') - f.write("\n") - f.write(ids_str) - f.close() - + ET.ElementTree(ids_schema.encode(self.asdict())).write(filepath, encoding="utf-8", xml_declaration=True) return ids_schema.is_valid(filepath) @staticmethod diff --git a/src/ifcopenshell-python/test/test_ids.py b/src/ifcopenshell-python/test/test_ids.py index 5877cab15d..7dd46ca878 100644 --- a/src/ifcopenshell-python/test/test_ids.py +++ b/src/ifcopenshell-python/test/test_ids.py @@ -95,11 +95,18 @@ class TestIdsParsing(unittest.TestCase): def test_parsed_ids_to_xml(self): IDS_URL = os.path.join(os.path.dirname(__file__), "Sample-BIM-Files", "IDS", "IDS_Wall_needs_all_fields.xml") ids_file = ids.ids.open(IDS_URL) - fn = "TEST_FILE.xml" + fn = "output.xml" result = ids_file.to_xml(fn) + assert os.path.isfile(fn) os.remove(fn) self.assertTrue(result) + def test_parsed_ids_to_string(self): + IDS_URL = os.path.join(os.path.dirname(__file__), "Sample-BIM-Files", "IDS", "IDS_Wall_needs_all_fields.xml") + ids_file = ids.ids.open(IDS_URL) + output = ids_file.to_string() + assert output and "http://standards.buildingsmart.org/IDS" in output + """ Parsing IDS files with restrictions """ def test_parse_restrictions_enumeration(self):