from xml.dom import minidom from distutils.util import strtobool from lottie.nvector import NVector from lottie.parsers.sif.sif.frame_time import FrameTime class _tag: def __init__(self, type): self.type = type def __call__(self, v): return self.type(v) bool_str = _tag(bool) def str_to_bool(strval): return bool(strtobool(strval)) def value_from_xml_string(xml_str, type, registry): if type in (bool_str, bool): return str_to_bool(xml_str) elif type is NVector: return NVector(*map(float, xml_str.split())) if type is FrameTime: return FrameTime.parse_string(xml_str, registry) return type(xml_str) def value_to_xml_string(value, type): if type is bool: return "1" if value else "0" if type is bool_str: return "true" if value else "false" elif type is NVector: return " ".join(map(str, value)) return str(value) def value_isinstance(value, type): if isinstance(type, _tag): type = type.type return isinstance(value, type) def xml_text(node): return "".join( x.nodeValue for x in node.childNodes if x.nodeType in {minidom.Node.TEXT_NODE, minidom.Node.CDATA_SECTION_NODE} ) def xml_make_text(dom: minidom.Document, tag_name, text): e = dom.createElement(tag_name) e.appendChild(dom.createTextNode(text)) return e def xml_element_matches(ch: minidom.Node, tagname=None): if ch.nodeType != minidom.Node.ELEMENT_NODE: return False if tagname is not None and ch.tagName != tagname: return False return True def xml_child_elements(xml: minidom.Node, tagname=None): for ch in xml.childNodes: if xml_element_matches(ch, tagname): yield ch def xml_first_element_child(xml: minidom.Node, tagname=None, allow_none=False): for ch in xml_child_elements(xml, tagname): return ch if allow_none: return None raise ValueError("No %s in %s" % (tagname or "child element", getattr(xml, "tagName", "node")))