Or if you would like a bit more refined functionality, like preserving already existing tags, removing descriptions and so on
import os
import xml.etree.ElementTree as ET
def find_xml_element(parent_element, tag, attribs=None):
options = parent_element.findall(tag)
if len(options) == 0:
return None
else:
if attribs is None:
return options[0]
for o in options:
if o.attrib == attribs:
return o
else:
return None
def writePAMfile(img, descriptions=None):
n_bands = img.count
if isinstance(descriptions, list):
if not len(descriptions) == n_bands:
raise ValueError("You must pass one description string for every band")
elif descriptions is None:
descriptions = img.descriptions
else:
raise TypeError("The argument 'descriptions' must be a list of strings or None")
pam_path = os.path.abspath('.'.join([img.files[0], 'aux.xml']))
if os.path.isfile(pam_path):
tree = ET.parse(pam_path)
root = tree.getroot()
if root.tag != 'PAMDataset':
raise RuntimeError("a XML file {0} exists but is not recognized as a valid PAM dataset".format(pam_path))
else:
for n, d in enumerate(descriptions):
band = find_xml_element(root, "PAMRasterBand", {'band':str(n + 1)})
if band is None:
band = ET.SubElement(root, "PAMRasterBand", band=str(n+1))
meta = band.find("Metadata")
if meta is None:
meta = ET.SubElement(band, 'Metadata')
mdi = find_xml_element(meta, "MDI", {'key':'BandName'})
if mdi is None:
ET.SubElement(meta, "MDI", key="BandName").text = str(d)
else:
mdi.text = str(d)
desc = band.find("Description")
if d is not None:
if desc is None:
ET.SubElement(band, "Description").text = d
else:
desc.text = d
else:
if desc is not None:
band.remove(desc)
else:
root = ET.Element("PAMDataset")
for n, d in enumerate(descriptions):
band = ET.SubElement(root, "PAMRasterBand", band=str(n+1))
meta = ET.SubElement(band, 'Metadata')
if isinstance(d, str):
ET.SubElement(meta, "MDI", key="BandName").text = d
ET.SubElement(band, "Description").text = d
elif d is None:
ET.SubElement(meta, "MDI", key="BandName").text = "None"
else:
raise ValueError("Descriptions must be a str or None")
tree = ET.ElementTree(root)
tree.write(pam_path)