IfcTester can now read from XML strings in addition to opening files on disk

This commit is contained in:
Dion Moult
2025-01-14 13:35:45 +11:00
parent adcc23541a
commit ec600ec72e
2 changed files with 25 additions and 23 deletions
+14 -5
View File
@@ -50,11 +50,7 @@ class IdsXmlValidationError(Exception):
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]:
def open(filepath: str, validate: bool = False) -> Ids:
try:
if validate:
get_schema().validate(filepath)
@@ -66,6 +62,19 @@ def open(filepath: str, validate=False) -> Union[Ids, None]:
return Ids().parse(decode)
def from_string(xml: str, validate: bool = False) -> Ids:
tree = ET.ElementTree(ET.fromstring(xml))
try:
if validate:
get_schema().validate(tree)
decode = get_schema().decode(
tree, strip_namespaces=True, namespaces={"": "http://standards.buildingsmart.org/IDS"}
)
except XMLSchemaValidationError as e:
raise IdsXmlValidationError(e, "Provided XML appears to be invalid. See details above.")
return Ids().parse(decode)
def get_schema():
global schema
if schema is None:
+11 -18
View File
@@ -65,6 +65,15 @@ class TestIds:
"specifications": {"specification": []},
}
def test_reading_an_ids_from_an_xml_string(self):
specs = ids.Ids()
spec = ids.Specification(name="Name")
spec.applicability.append(ids.Entity(name="IFCWALL"))
specs.specifications.append(spec)
xml = specs.to_string()
specs2 = ids.from_string(xml)
assert len(specs2.specifications) == 1
def test_create_an_ids_with_all_possible_information(self):
specs = ids.Ids(
title="title",
@@ -117,7 +126,7 @@ class TestIds:
spec.requirements.append(ids.Attribute(name="Name", value="Waldo"))
specs.specifications.append(spec)
fn = "tmp.xml"
result = specs.to_xml(fn)
specs.to_xml(fn)
os.remove(fn)
def test_creating_a_minimal_ids_and_validating(self):
@@ -187,27 +196,11 @@ class TestIds:
spec.set_usage("optional")
model = ifcopenshell.file()
wall = model.createIfcWall(Name="Waldo")
spec.requirements.append(description_attr := ids.Attribute(name="Description", value="Foobar"))
spec.requirements.append(ids.Attribute(name="Description", value="Foobar"))
run("A specification passes only if all requirements pass 1/2", specs, model, False, [wall], [wall])
wall.Description = "Foobar"
run("A specification passes only if all requirements pass 2/2", specs, model, True, [wall])
# optional attribute
# description_attr.minOccurs = 0
# description_attr.maxOccurs = "unbounded"
# wall.Description = None
# run("Specification optionality and facet optionality can be combined", specs, model, True, [wall])
# double negative / required attributes
# spec.set_usage("prohibited")
# name_attr.minOccurs = 0
# name_attr.maxOccurs = 0
# description_attr.minOccurs = 0
# description_attr.maxOccurs = 0
# wall.Name = "Waldo"
# wall.Description = "Foobar"
# run("A prohibited specification and a prohibited facet results in a double negative", specs, model, True, [wall])
# specs independency
specs = ids.Ids(title="Title")
spec = ids.Specification(name="Name")