diff --git a/drafthorse/models/container.py b/drafthorse/models/container.py index 30cdfe3..56f36dd 100644 --- a/drafthorse/models/container.py +++ b/drafthorse/models/container.py @@ -80,10 +80,10 @@ def empty_element(self): def set_element(self, el, child): el._text = child[1] - el._scheme_id = child[0] + el._scheme_id = child[0] or "" def add_from_etree(self, root, strict=True): - self.add((root.attrib["schemeID"], root.text)) + self.add((root.attrib.get("schemeID"), root.text)) class StringContainer(SimpleContainer): diff --git a/drafthorse/models/elements.py b/drafthorse/models/elements.py index 31a0e3d..81efca7 100644 --- a/drafthorse/models/elements.py +++ b/drafthorse/models/elements.py @@ -236,7 +236,7 @@ def to_etree(self): return node def from_etree(self, root, strict=True): - self._text = Decimal(root.text) + self._text = root.text self._list_id = root.attrib["listID"] self._list_version_id = root.attrib["listVersionID"] self._set_on_input = True @@ -389,9 +389,11 @@ def to_etree(self): def from_etree(self, root, strict=True): try: - self._value = datetime.strptime(root.text, "%Y-%m-%dT%H:%M:%S").date() - except Exception: - self._value = "" + self._value = datetime.strptime(root.text, "%Y-%m-%dT%H:%M:%S") + except ValueError: + if strict: + raise + self._value = None self._set_on_input = True return self diff --git a/tests/test_elements.py b/tests/test_elements.py new file mode 100644 index 0000000..d0e0d8a --- /dev/null +++ b/tests/test_elements.py @@ -0,0 +1,46 @@ +import xml.etree.cElementTree as ET +from datetime import datetime + +import pytest + +from drafthorse.models import NS_RAM +from drafthorse.models.container import IDContainer +from drafthorse.models.elements import ClassificationElement, DirectDateTimeElement + + +def test_classification_element_roundtrip_non_numeric_text(): + el = ClassificationElement(NS_RAM, "ClassCode") + el._text = "ABC123" + el._list_id = "TST" + el._list_version_id = "1" + node = el.to_etree() + + parsed = ClassificationElement(NS_RAM, "ClassCode").from_etree(node) + assert parsed._text == "ABC123" + assert parsed._list_id == "TST" + assert parsed._list_version_id == "1" + + +def test_direct_datetime_roundtrip_keeps_time(): + el = DirectDateTimeElement(NS_RAM, "CreationDateTime") + el._value = datetime(2024, 5, 3, 14, 30, 45) + node = el.to_etree() + assert node.text == "2024-05-03T14:30:45" + + parsed = DirectDateTimeElement(NS_RAM, "CreationDateTime").from_etree(node) + assert parsed._value == datetime(2024, 5, 3, 14, 30, 45) + + +def test_direct_datetime_invalid_raises_in_strict_mode(): + node = ET.Element("{%s}CreationDateTime" % NS_RAM) + node.text = "not-a-date" + with pytest.raises(ValueError): + DirectDateTimeElement(NS_RAM, "CreationDateTime").from_etree(node, strict=True) + + +def test_id_container_accepts_missing_scheme_id(): + node = ET.Element("{%s}GlobalID" % NS_RAM) + node.text = "4000001123452" + container = IDContainer(child_type=(tuple, list), namespace=NS_RAM, tag="GlobalID") + container.add_from_etree(node) + assert container.children == [(None, "4000001123452")]