Added inheritance support to XML material profile deserialization

CURA-2108
This commit is contained in:
Jaime van Kessel 2016-08-30 14:48:34 +02:00
parent 91c11ee0fc
commit 6a2e5ffe77

View file

@ -7,8 +7,10 @@ import io
import xml.etree.ElementTree as ET
import uuid
from UM.Resources import Resources
from UM.Logger import Logger
from UM.Util import parseBool
from cura.CuraApplication import CuraApplication
import UM.Dictionary
@ -246,6 +248,51 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
return stream.getvalue()
# Recursively resolve loading inherited files
def _resolveInheritance(self, file_name):
xml = self._loadFile(file_name)
inherits = xml.find("./um:inherits", self.__namespaces)
if inherits is not None:
inherited = self._resolveInheritance(inherits.text)
xml = self._mergeXML(inherited, xml)
return xml
def _loadFile(self, file_name):
path = Resources.getPath(CuraApplication.getInstance().ResourceTypes.MaterialInstanceContainer, file_name + ".xml.fdm_material")
contents = {}
with open(path, encoding="utf-8") as f:
contents = f.read()
#self._inherited_files.append(path)
return ET.fromstring(contents)
def _mergeXML(self, first, second):
result = copy.deepcopy(first)
self._combineElement(result, second)
return result
# Recursively merges XML elements. Updates either the text or children if another element is found in first.
# If it does not exist, copies it from second.
def _combineElement(self, first, second):
# Create a mapping from tag name to element.
mapping = {el.tag: el for el in first}
for el in second:
if len(el): # Check if element has children.
try:
self._combineElement(mapping[el.tag], el) # Multiple elements, handle those.
except KeyError:
mapping[el.tag] = el
first.append(el)
else:
try:
mapping[el.tag].text = el.text
except KeyError: # Not in the mapping, so simply add it
mapping[el.tag] = el
first.append(el)
## Overridden from InstanceContainer
def deserialize(self, serialized):
data = ET.fromstring(serialized)
@ -255,6 +302,11 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
# TODO: Add material verfication
self.addMetaDataEntry("status", "unknown")
#for inherit in data.findall("./um:inherits", self.__namespaces):
inherits = data.find("./um:inherits", self.__namespaces)
if inherits is not None:
inherited = self._resolveInheritance(inherits.text)
data = self._mergeXML(inherited, data)
metadata = data.iterfind("./um:metadata/*", self.__namespaces)
for entry in metadata: