self.to_etree(), "utf-8"
)
return validate_xml(xmlout=xml, schema=schema)
+
+ def __setattr__(self, key, value):
+ if not hasattr(self, key) and not key.startswith("_") and not key in ("required",):
+ raise AttributeError(f"Element {type(self)} has no attribute '{key}'. If you set it, it would not be included in the output.")
+ return super().__setattr__(key, value)
def from_etree(self, root):
if (
class StringElement(Element):
def __init__(self, namespace, tag, text=""):
super().__init__()
- self.namespace = namespace
- self.tag = tag
- self.text = text
- self.set_on_input = False
+ self._namespace = namespace
+ self._tag = tag
+ self._text = text
+ self._set_on_input = False
def __repr__(self):
return "<{}: {}>".format(type(self).__name__, str(self))
return str(self.text)
def is_empty(self, el):
- return super().is_empty(el) and not self.set_on_input
+ return super().is_empty(el) and not self._set_on_input
def get_tag(self):
- return "{%s}%s" % (self.namespace, self.tag)
+ return "{%s}%s" % (self._namespace, self._tag)
def to_etree(self):
node = self._etree_node()
- node.text = self.text
+ node.text = self._text
return node
def from_etree(self, root):
- self.text = root.text
- self.set_on_input = True
+ self._text = root.text
+ self._set_on_input = True
return self
class DecimalElement(StringElement):
def __init__(self, namespace, tag, value=None):
super().__init__(namespace, tag)
- self.value = value
+ self._value = value
def to_etree(self):
node = self._etree_node()
- node.text = str(self.value) if self.value is not None else ""
+ node.text = str(self._value) if self._value is not None else ""
return node
def __str__(self):
return self.value
def from_etree(self, root):
- self.value = Decimal(root.text)
- self.set_on_input = True
+ self._value = Decimal(root.text)
+ self._set_on_input = True
return self
class QuantityElement(StringElement):
def __init__(self, namespace, tag, amount="", unit_code=""):
super().__init__(namespace, tag)
- self.amount = amount
- self.unit_code = unit_code
+ self._amount = amount
+ self._unit_code = unit_code
def to_etree(self):
node = self._etree_node()
- node.text = str(self.amount)
- node.attrib["unitCode"] = self.unit_code
+ node.text = str(self._amount)
+ node.attrib["unitCode"] = self._unit_code
return node
def __str__(self):
- return "{} {}".format(self.amount, self.unit_code)
+ return "{} {}".format(self._amount, self._unit_code)
def from_etree(self, root):
- self.amount = Decimal(root.text)
- self.unit_code = root.attrib["unitCode"]
- self.set_on_input = True
+ self._amount = Decimal(root.text)
+ self._unit_code = root.attrib["unitCode"]
+ self._set_on_input = True
return self
class CurrencyElement(StringElement):
def __init__(self, namespace, tag, amount="", currency=None):
super().__init__(namespace, tag)
- self.amount = amount
- self.currency = currency
+ self._amount = amount
+ self._currency = currency
def to_etree(self):
node = self._etree_node()
- node.text = str(self.amount)
- if self.currency is not None:
- node.attrib["currencyID"] = self.currency
+ node.text = str(self._amount)
+ if self._currency is not None:
+ node.attrib["currencyID"] = self._currency
elif "currencyID" in node.attrib:
del node.attrib["currencyID"]
return node
def from_etree(self, root):
- self.amount = Decimal(root.text)
- self.currency = root.attrib.get("currencyID") or None
- self.set_on_input = True
+ self._amount = Decimal(root.text)
+ self._currency = root.attrib.get("currencyID") or None
+ self._set_on_input = True
return self
def __str__(self):
class ClassificationElement(StringElement):
def __init__(self, namespace, tag, text="", list_id="", list_version_id=""):
super().__init__(namespace, tag)
- self.text = text
- self.list_id = list_id
- self.list_version_id = list_version_id
+ self._text = text
+ self._list_id = list_id
+ self._list_version_id = list_version_id
def to_etree(self):
node = self._etree_node()
node.text = self.text
- node.attrib["listID"] = self.list_id
- node.attrib["listVersionID"] = self.list_version_id
+ node.attrib["listID"] = self._list_id
+ node.attrib["listVersionID"] = self._list_version_id
return node
def from_etree(self, root):
- self.text = Decimal(root.text)
- self.list_id = root.attrib["listID"]
- self.list_version_id = root.attrib["listVersionID"]
- self.set_on_input = True
+ self._text = Decimal(root.text)
+ self._list_id = root.attrib["listID"]
+ self._list_version_id = root.attrib["listVersionID"]
+ self._set_on_input = True
return self
def __str__(self):
- return "{} ({} {})".format(self.text, self.list_id, self.list_version_id)
+ return "{} ({} {})".format(self._text, self._list_id, self._list_version_id)
class BinaryObjectElement(StringElement):
def __init__(self, namespace, tag, text="", filename="", mime_code=""):
super().__init__(namespace, tag)
- self.mime_code = mime_code
- self.filename = filename
- self.text = text
+ self._mime_code = mime_code
+ self._filename = filename
+ self._text = text
def to_etree(self):
node = self._etree_node()
- node.attrib["mimeCode"] = self.mime_code
- node.attrib["filename"] = self.filename
- node.text = self.text
+ node.attrib["mimeCode"] = self._mime_code
+ node.attrib["filename"] = self._filename
+ node.text = self._text
return node
def from_etree(self, root):
- self.mime_code = root.attrib["mimeCode"]
- self.filename = root.attrib["filename"]
- self.text = root.text
- self.set_on_input = True
+ self._mime_code = root.attrib["mimeCode"]
+ self._filename = root.attrib["filename"]
+ self._text = root.text
+ self._set_on_input = True
return self
def __str__(self):
- return "{} ({} {})".format(self.text, self.mime_code)
+ return "{} ({} {})".format(self._text, self._mime_code)
class AgencyIDElement(StringElement):
def __init__(self, namespace, tag, text="", scheme_id=""):
super().__init__(namespace, tag)
- self.text = text
- self.scheme_id = scheme_id
+ self._text = text
+ self._scheme_id = scheme_id
def to_etree(self):
node = self._etree_node()
- node.text = self.text
- node.attrib["schemeAgencyID"] = self.scheme_id
+ node.text = self._text
+ node.attrib["schemeAgencyID"] = self._scheme_id
return node
def from_etree(self, root):
- self.text = root.text
- self.scheme_id = root.attrib["schemeAgencyID"]
- self.set_on_input = True
+ self._text = root.text
+ self._scheme_id = root.attrib["schemeAgencyID"]
+ self._set_on_input = True
return self
def __str__(self):
- return "{} ({})".format(self.text, self.scheme_id)
+ return "{} ({})".format(self._text, self._scheme_id)
class IDElement(StringElement):
def __init__(self, namespace, tag, text="", scheme_id=""):
super().__init__(namespace, tag)
- self.text = text
- self.scheme_id = scheme_id
+ self._text = text
+ self._scheme_id = scheme_id
def to_etree(self):
node = self._etree_node()
- node.text = self.text
- node.attrib["schemeID"] = self.scheme_id
+ node.text = self._text
+ node.attrib["schemeID"] = self._scheme_id
return node
def from_etree(self, root):
- self.text = root.text
+ self._text = root.text
try:
- self.scheme_id = root.attrib["schemeID"]
+ self._scheme_id = root.attrib["schemeID"]
except:
root.attrib["schemeID"] = ""
- self.scheme_id = root.attrib["schemeID"]
- self.set_on_input = True
+ self._scheme_id = root.attrib["schemeID"]
+ self._set_on_input = True
return self
def __str__(self):
- return "{} ({})".format(self.text, self.scheme_id)
+ return "{} ({})".format(self._text, self._scheme_id)
class DateTimeElement(StringElement):
def __init__(self, namespace, tag, value=None, format="102"):
super().__init__(namespace, tag)
- self.value = value
- self.format = format
+ self._value = value
+ self._format = format
def to_etree(self):
t = self._etree_node()
node = ET.Element("{%s}%s" % (NS_UDT, "DateTimeString"))
- if self.value:
- if self.format == "102":
- node.text = self.value.strftime("%Y%m%d")
- elif self.format == "616":
+ if self._value:
+ if self._format == "102":
+ node.text = self._value.strftime("%Y%m%d")
+ elif self._format == "616":
if sys.version_info < (3, 6):
node.text = "{}{}".format(
- self.value.isocalendar()[0], self.value.isocalendar()[1]
+ self._value.isocalendar()[0], self._value.isocalendar()[1]
)
else:
- node.text = self.value.strftime("%G%V")
- node.attrib["format"] = self.format
+ node.text = self._value.strftime("%G%V")
+ node.attrib["format"] = self._format
t.append(node)
return t
raise TypeError("Date containers should have one child")
if root[0].tag != "{%s}%s" % (NS_UDT, "DateTimeString"):
raise TypeError("Tag %s not recognized" % root[0].tag)
- self.format = root[0].attrib["format"]
- if self.format == "102":
- self.value = datetime.strptime(root[0].text, "%Y%m%d").date()
- elif self.format == "616":
+ self._format = root[0].attrib["format"]
+ if self._format == "102":
+ self._value = datetime.strptime(root[0].text, "%Y%m%d").date()
+ elif self._format == "616":
if sys.version_info < (3, 6):
from isoweek import Week
w = Week(int(root[0].text[:4]), int(root[0].text[4:]))
- self.value = w.monday()
+ self._value = w.monday()
else:
- self.value = datetime.strptime(root[0].text + "1", "%G%V%u").date()
+ self._value = datetime.strptime(root[0].text + "1", "%G%V%u").date()
else:
raise TypeError(
"Date format %s cannot be parsed" % root[0].attrib["format"]
)
- self.set_on_input = True
+ self._set_on_input = True
return self
def __str__(self):
- return "{}".format(self.value)
+ return "{}".format(self._value)
class DirectDateTimeElement(StringElement):
def __init__(self, namespace, tag, value=None):
super().__init__(namespace, tag)
- self.value = value
- self.format = format
+ self._value = value
def to_etree(self):
t = self._etree_node()
- if self.value:
- t.text = self.value.strftime("%Y-%m-%dT%H:%M:%S")
+ if self._value:
+ t.text = self._value.strftime("%Y-%m-%dT%H:%M:%S")
return t
def from_etree(self, root):
try:
- self.value = datetime.strptime(root.text, "%Y-%m-%dT%H:%M:%S").date()
+ self._value = datetime.strptime(root.text, "%Y-%m-%dT%H:%M:%S").date()
except:
- self.value = ""
- self.set_on_input = True
+ self._value = ""
+ self._set_on_input = True
return self
def __str__(self):
- return "{}".format(self.value)
+ return "{}".format(self._value)
class IndicatorElement(StringElement):
def __init__(self, namespace, tag, value=None):
super().__init__(namespace, tag)
- self.value = value
+ self._value = value
def get_tag(self):
- return "{%s}%s" % (self.namespace, self.tag)
+ return "{%s}%s" % (self._namespace, self._tag)
def to_etree(self):
t = self._etree_node()
- if self.value is None:
+ if self._value is None:
return t
node = ET.Element("{%s}%s" % (NS_UDT, "Indicator"))
- node.text = str(self.value).lower()
+ node.text = str(self._value).lower()
t.append(node)
return t
def __str__(self):
- return "{}".format(self.value)
+ return "{}".format(self._value)
def from_etree(self, root):
if len(root) != 1:
raise TypeError("Indicator containers should have one child")
if root[0].tag != "{%s}%s" % (NS_UDT, "Indicator"):
raise TypeError("Tag %s not recognized" % root[0].tag)
- self.value = root[0].text == "true"
- self.set_on_input = True
+ self._value = root[0].text == "true"
+ self._set_on_input = True
return self
def __set__(self, instance, value):
if instance._data.get(self.name, None) is None:
instance._data[self.name] = self.initialize()
- instance._data[self.name].text = value
+ instance._data[self.name]._text = value
class AgencyIDField(Field):
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 2-tuple of scheme agency ID and ID.")
- instance._data[self.name].text = value[1]
- instance._data[self.name].scheme_id = value[0]
+ instance._data[self.name]._text = value[1]
+ instance._data[self.name]._scheme_id = value[0]
class ClassificationField(Field):
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 3-tuple of list ID, list version and ID.")
- instance._data[self.name].text = value[2]
- instance._data[self.name].list_id = value[0]
- instance._data[self.name].list_version_id = value[1]
+ instance._data[self.name]._text = value[2]
+ instance._data[self.name]._list_id = value[0]
+ instance._data[self.name]._list_version_id = value[1]
class IDField(Field):
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 2-tuple of including scheme ID and ID.")
- instance._data[self.name].text = value[1]
- instance._data[self.name].scheme_id = value[0]
+ instance._data[self.name]._text = value[1]
+ instance._data[self.name]._scheme_id = value[0]
class CurrencyField(Field):
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 2-tuple of including amount and currency.")
- instance._data[self.name].amount = value[0]
- instance._data[self.name].currency = value[1]
+ instance._data[self.name]._amount = value[0]
+ instance._data[self.name]._currency = value[1]
def initialize(self):
return self.cls(self.namespace, self.tag)
def __set__(self, instance, value):
if instance._data.get(self.name, None) is None:
instance._data[self.name] = self.initialize()
- instance._data[self.name].value = value
+ instance._data[self.name]._value = value
def initialize(self):
return self.cls(self.namespace, self.tag)
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 2-tuple of including amount and unit code.")
- instance._data[self.name].amount = value[0]
- instance._data[self.name].unit_code = value[1]
+ instance._data[self.name]._amount = value[0]
+ instance._data[self.name]._unit_code = value[1]
def initialize(self):
return self.cls(self.namespace, self.tag)
if not isinstance(value, (tuple, list)):
raise TypeError("Please pass a 2-tuple of including amount and unit code.")
- instance._data[self.name].text = value[2]
- instance._data[self.name].mime_code = value[0]
- instance._data[self.name].filename = value[1]
+ instance._data[self.name]._text = value[2]
+ instance._data[self.name]._mime_code = value[0]
+ instance._data[self.name]._filename = value[1]
def initialize(self):
return self.cls(self.namespace, self.tag)
def __set__(self, instance, value):
if instance._data.get(self.name, None) is None:
instance._data[self.name] = self.initialize()
- instance._data[self.name].value = value
+ instance._data[self.name]._value = value
def initialize(self):
return self.cls(self.namespace, self.tag)
def __set__(self, instance, value):
if instance._data.get(self.name, None) is None:
instance._data[self.name] = self.initialize()
- instance._data[self.name].value = value
+ instance._data[self.name]._value = value
def initialize(self):
return self.cls(self.namespace, self.tag)
def __set__(self, instance, value):
if instance._data.get(self.name, None) is None:
instance._data[self.name] = self.initialize()
- instance._data[self.name].value = value
+ instance._data[self.name]._value = value
def initialize(self):
return self.cls(self.namespace, self.tag)