ifctester to fail more gracefully meeting invalid .ids file

Previously Bonsai would show a wall of errors, now it's show a simple error message and redirecting to system console for the details.

Example error - https://i.imgur.com/uJJfjUW.png
Example validation error details in console - https://i.imgur.com/3mcVBUh.png

Same details but in text:
Validation error details:

failed validating {'dataType': 'IFCBOOLEAN', 'ursi': 'https://google.com', 'cardinality': 'required', 'instructions': "Make sure it's true"} with XsdAttributeGroup(['dataType', 'uri', 'cardinality', 'instructions']):

Reason: 'ursi' attribute not allowed for element

Schema component:

  <xs:extension xmlns:xs="http://www.w3.org/2001/XMLSchema" base="ids:propertyType">
      <xs:attribute name="uri" type="xs:anyURI" use="optional" />
      <xs:attribute name="cardinality" type="ids:conditionalCardinality" use="optional" default="required" />
      <xs:attribute name="instructions" type="xs:string" use="optional">
          <xs:annotation>
              <xs:documentation>Author of the IDS can leave instructions for the authors of the IFC. This text could/should be displayed in the BIM/IFC authoring tool.</xs:documentation>
          </xs:annotation>
      </xs:attribute>
  </xs:extension>

Instance type: <class 'xml.etree.ElementTree.Element'>

Instance:

  <ids:property xmlns:ids="http://standards.buildingsmart.org/IDS" dataType="IFCBOOLEAN" ursi="https://google.com" cardinality="required" instructions="Make sure it's true">
    <ids:propertySet>
      <ids:simpleValue>Pset_WallCommon</ids:simpleValue>
    </ids:propertySet>
    <ids:baseName>
      <ids:simpleValue>Combustible</ids:simpleValue>
    </ids:baseName>
    <ids:value>
      <ids:simpleValue>false</ids:simpleValue>
    </ids:value>
  </ids:property>

Path: /ids:ids/ids:specifications/ids:specification/ids:requirements/ids:property[1]
This commit is contained in:
Andrej730
2024-11-08 14:48:43 +05:00
parent 0a7ee4e360
commit f7a7626575
2 changed files with 30 additions and 6 deletions
@@ -21,6 +21,7 @@ import bpy
import time
import tempfile
import webbrowser
import traceback
import ifctester
import ifctester.ids
import ifctester.reporter
@@ -72,7 +73,19 @@ class ExecuteIfcTester(bpy.types.Operator, tool.Ifc.Operator):
start = time.time()
output = Path(os.path.join(dirpath, "{}_{}.html".format(ifc_path, os.path.basename(specs_path))))
specs = ifctester.ids.open(specs_path)
try:
specs = ifctester.ids.open(specs_path)
except ifctester.ids.IdsXmlValidationError as e:
traceback.print_exc()
YELLOW = "\033[93m"
RESET = "\033[0m"
print("------------------\n" * 3)
print(f"{YELLOW}Validation error details:\n\n{str(e.xml_error)}{RESET}")
print("------------------\n" * 3)
self.report(
{"ERROR"}, "Provided IDS file appears to be invalid. Open system console to see the details."
)
return {"CANCELLED"}
print("Finished loading:", time.time() - start)
start = time.time()
specs.validate(ifc_data, filepath=ifc_path)
+16 -5
View File
@@ -20,6 +20,7 @@ from __future__ import annotations
import os
import datetime
import ifcopenshell
from xmlschema.validators.exceptions import XMLSchemaValidationError
from xmlschema import XMLSchema
from xmlschema import etree_tostring
from xml.etree import ElementTree as ET
@@ -43,16 +44,26 @@ cwd = os.path.dirname(os.path.realpath(__file__))
schema = None
class IdsXmlValidationError(Exception):
def __init__(self, xml_error: XMLSchemaValidationError, message: str):
self.xml_error = xml_error
super().__init__(message)
@overload
def open(filepath: str, validate: Literal[False] = False) -> Ids: ...
@overload
def open(filepath: str, validate: Literal[True]) -> None: ...
def open(filepath: str, validate=False) -> Union[Ids, None]:
if validate:
get_schema().validate(filepath)
return Ids().parse(
get_schema().decode(filepath, strip_namespaces=True, namespaces={"": "http://standards.buildingsmart.org/IDS"})
)
try:
if validate:
get_schema().validate(filepath)
decode = get_schema().decode(
filepath, strip_namespaces=True, namespaces={"": "http://standards.buildingsmart.org/IDS"}
)
except XMLSchemaValidationError as e:
raise IdsXmlValidationError(e, f"Provided .ids file ({filepath}) appears to be invalid. See details above.")
return Ids().parse(decode)
def get_schema():