Skip to content

Commit

Permalink
Add complex_type test
Browse files Browse the repository at this point in the history
  • Loading branch information
multimeric committed Jan 3, 2025
1 parent 5ea3fac commit 1f466b6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
11 changes: 9 additions & 2 deletions schema_automator/importers/xsd_import_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,16 +594,23 @@ def visit_schema(self, schema: etree._Element) -> None:
# Ensure that the target namespace ends with a slash
self.target_ns += "/"

attributes: dict[str, SlotDefinition] = {}
for child in schema:
if child.tag == f"{{{XSD}}}element":
definition = self.visit_element(child)
if isinstance(definition, ClassDefinition):
self.sb.add_class(definition)
attributes[definition.name] = definition
elif child.tag == f"{{{XSD}}}complexType":
# complexType can be at the top level
cls = ClassDefinition(name=PLACEHOLDER_NAME)
self.visit_complex_type(child, cls)
self.sb.add_class(cls)
schema_root = ClassDefinition(
name="SchemaRoot",
class_uri=urljoin(self.target_ns, "SchemaRoot") if self.target_ns else None,
attributes=attributes,
description="Entry point of the schema, treated as a class",
)
self.sb.add_class(schema_root)

def convert(self, file: str, **kwargs: Any) -> SchemaDefinition:
parser = etree.XMLParser(remove_blank_text=True)
Expand Down
39 changes: 34 additions & 5 deletions tests/test_importers/test_xsd_importer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from linkml_runtime.linkml_model.meta import SchemaDefinition
from linkml_runtime import SchemaView
from schema_automator.importers import XsdImportEngine
import tempfile

def parse_string(xsd: str) -> SchemaDefinition:
def parse_string(xsd: str) -> SchemaView:
engine = XsdImportEngine()
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write('''<xsd:schema
Expand All @@ -15,8 +15,37 @@ def parse_string(xsd: str) -> SchemaDefinition:
''')
f.write(xsd)
f.write("</xsd:schema>")
return engine.convert(f.name)
schema = engine.convert(f.name)
return SchemaView(schema)

def test_embedded_type():
schema = parse_string('<xsd:element name="AcquisitionDate" minOccurs="0" maxOccurs="1" type="xsd:dateTime"/>')
assert True
schema = parse_string('<xsd:element name="AcquisitionDate" type="xsd:dateTime"/>')
assert len(schema.all_classes()) == 1
root = schema.get_class("SchemaRoot")
assert len(root.attributes) == 1
assert root.attributes["acquisitionDate"].range == "DateTime"

def test_complex_type():
schema = parse_string('''
<xsd:element name="MyClass">
<xsd:annotation>
<xsd:documentation>
Some docs
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="elementSlotA" type="xsd:float"/>
<xsd:element name="elementSlotB" type="xsd:integer"/>
</xsd:sequence>
<xsd:attribute name="attributeSlot" type="xsd:boolean"/>
</xsd:complexType>
</xsd:element>
''')
assert len(schema.all_classes()) == 2
my_class = schema.get_class("MyClass")
assert len(my_class.attributes) == 3
assert my_class.attributes["elementSlotA"].range == "Float"
assert my_class.attributes["elementSlotB"].range == "Integer"
assert my_class.attributes["attributeSlot"].range == "Boolean"
assert my_class.description == "Some docs"

0 comments on commit 1f466b6

Please sign in to comment.