Source code for fastpyxl.descriptors.nested
# Copyright (c) 2010-2024 fastpyxl
"""
Generic serialisable classes.
"""
from fastpyxl.compat import safe_string
from fastpyxl.xml.functions import Element, localname, whitespace
from .base import Bool, Convertible, Descriptor, Float, Integer, MinMax, NoneSet, Set, String
[docs]
class Nested(Descriptor):
nested = True
attribute = "val"
def __set__(self, instance, value):
if hasattr(value, "tag"):
tag = localname(value)
if tag != self.name:
raise ValueError("Tag does not match attribute")
value = self.from_tree(value)
super().__set__(instance, value)
[docs]
def from_tree(self, node):
return node.get(self.attribute)
[docs]
def to_tree(self, tagname=None, value=None, namespace=None):
namespace = self.namespace or namespace
if value is not None:
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
assert tagname is not None
value = safe_string(value)
return Element(tagname, {self.attribute: value})
[docs]
class NestedValue(Nested, Convertible):
"""
Nested tag storing the value on the 'val' attribute.
"""
[docs]
class NestedText(NestedValue):
"""
Represents any nested tag with the value as the contents of the tag.
"""
[docs]
def from_tree(self, node):
return node.text
[docs]
def to_tree(self, tagname=None, value=None, namespace=None):
namespace = self.namespace or namespace
if value is not None:
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
assert tagname is not None
el = Element(tagname)
el.text = safe_string(value)
whitespace(el)
return el
[docs]
class NestedFloat(NestedValue, Float):
pass
[docs]
class NestedInteger(NestedValue, Integer):
pass
[docs]
class NestedString(NestedValue, String):
pass
[docs]
class NestedBool(NestedValue, Bool):
[docs]
def from_tree(self, node):
return node.get("val", True)
[docs]
class NestedNoneSet(Nested, NoneSet):
pass
[docs]
class NestedSet(Nested, Set):
pass
[docs]
class NestedMinMax(Nested, MinMax):
pass
[docs]
class EmptyTag(Nested, Bool):
"""
Boolean if a tag exists or not.
"""
[docs]
def from_tree(self, node):
return True
[docs]
def to_tree(self, tagname=None, value=None, namespace=None):
if value:
namespace = self.namespace or namespace
if namespace is not None:
tagname = "{%s}%s" % (namespace, tagname)
assert tagname is not None
return Element(tagname)