我们从Python开源项目中,提取了以下50个代码示例,用于说明如何使用lxml.etree.SubElement()。
def _format_docdata(self, article, docdata): super()._format_docdata(article, docdata) if 'slugline' in article: key_list = etree.SubElement(docdata, 'key-list') etree.SubElement(key_list, 'keyword', attrib={'key': self._get_ntb_slugline(article)}) etree.SubElement( docdata, 'du-key', attrib={'version': str(_get_rewrite_sequence(article) + 1), 'key': self._get_ntb_slugline(article)}) for place in article.get('place', []): evloc = etree.SubElement(docdata, 'evloc') for key, att in (('parent', 'state-prov'), ('qcode', 'county-dist')): try: value = place[key] except KeyError: pass else: if value is not None: evloc.attrib[att] = value
def update(self, docs, commitwithin=None): """Post list of docs to Solr, return URL and status. Opptionall tell Solr to "commitwithin" that many milliseconds.""" url = self.url + '/update' add_xml = etree.Element('add') if commitwithin is not None: add_xml.set('commitWithin', str(commitwithin)) for doc in docs: xdoc = etree.SubElement(add_xml, 'doc') for key, value in doc.iteritems(): if value: field = etree.Element('field', name=key) field.text = (value if isinstance(value, unicode) else str(value)) xdoc.append(field) request = urllib2.Request(url) request.add_header('Content-Type', 'text/xml; charset=utf-8') request.add_data(etree.tostring(add_xml, pretty_print=True)) response = urllib2.urlopen(request).read() status = etree.XML(response).findtext('lst/int') return url, status
def save_projects(self, *args): root = ET.Element("projects") for project in self.projects_list: p = ET.SubElement(root, "project") ET.SubElement(p, "name").text = project.name ET.SubElement(p, "description").text = project.description ET.SubElement(p, "path").text = project.path ET.SubElement(p, "update").text = project.update_cmd ET.SubElement(p, "compile").text = project.compile_cmd ET.SubElement(p, "run").text = project.run_cmd if project.last_update is None: ET.SubElement(p, "last_update").text = None else: ET.SubElement(p, "last_update").text = project.last_update.strftime(settings.DATE_FORMAT) if project.last_compile is None: ET.SubElement(p, "last_compile").text = None else: ET.SubElement(p, "last_compile").text = project.last_compile.strftime(settings.DATE_FORMAT) tree = ET.ElementTree(root) tree.write(settings.PATH_PROJECT_FILE, pretty_print=True) logging.debug("All projects are saved")
def to_xml(self): """Produces an XML out of the point data. Disregards the "action" field.""" el = etree.Element(self.osm_type, id=str(self.osm_id), version=str(self.version)) for tag, value in self.tags.items(): etree.SubElement(el, 'tag', k=tag, v=value) if self.osm_type == 'node': el.set('lat', str(self.lat)) el.set('lon', str(self.lon)) elif self.osm_type == 'way': for node_id in self.members: etree.SubElement(el, 'nd', ref=str(node_id)) elif self.osm_type == 'relation': for member in self.members: m = etree.SubElement(el, 'member') for i, n in enumerate(('type', 'ref', 'role')): m.set(n, str(member[i])) return el
def getXML(self) : # return lxml etree element graphXML = etree.Element("graph",defaultedgetype=self.type,mode=self.mode,label=self.label,timeformat=self.time_format) for attributesElement in self.attributes.getAttributesDeclarationXML() : graphXML.append(attributesElement) nodesXML = etree.SubElement(graphXML, "nodes") node_ids=self._nodes.keys() node_ids.sort() for id in node_ids : nodesXML.append(self._nodes[id].getXML()) edgesXML = etree.SubElement(graphXML, "edges") edge_ids=self._edges.keys() edge_ids.sort() for id in edge_ids : edgesXML.append(self._edges[id].getXML()) return graphXML
def getAttributesDeclarationXML(self) : """ generate attributes declaration XML """ # return lxml etree element allAttributesXML=[] if len(self)>0 : # iter on node and then edge atts for attClass,atts in self.iteritems() : # group by mode key_mode=lambda att : att["mode"] atts_sorted_by_mode=sorted(atts.values(),key=key_mode,reverse=True) for mode,atts in itertools.groupby(atts_sorted_by_mode,key_mode) : # generate on attributes by mode attributesXML = etree.Element("attributes") attributesXML.set("class",attClass) attributesXML.set("mode",mode) # generate attribute by id order for att in sorted(atts,key=lambda att: att["id"]) : attributeXML=etree.SubElement(attributesXML, "attribute") attributeXML.set("id",str(att["id"])) attributeXML.set("title",att["title"]) attributeXML.set("type",att["type"]) if att["defaultValue"] : etree.SubElement(attributeXML, "default").text=att["defaultValue"] allAttributesXML.append(attributesXML) return allAttributesXML
def write(playlists: List[Playlist], target_path: Path, target_library_root: str, source_library_root: str, exclude_playlist_folders: bool = True) -> None: persistent_id_to_playlist_dict = create_persistent_id_to_playlist_dict(playlists) filtered_playlist = filter_playlists_if_necessary(playlists, exclude_playlist_folders) root = etree.Element("rhythmdb-playlists") for playlist in filtered_playlist: name = create_playlist_name(playlist, persistent_id_to_playlist_dict) attributes = {'name': name, 'show-browser': 'true', 'browser-position': "231", 'search-type': "search-match", 'type': "static"} playlist_element = etree.SubElement(root, "playlist", attributes) for song in playlist.tracks: if song.location_escaped is not None: transformed_location = transform_to_rhythmbox_path(song.location_escaped, target_library_root, source_library_root) location_element = etree.SubElement(playlist_element, "location") location_element.text = transformed_location else: print(" Can't convert the track [{} - {}] in playlist '{}' because there is no file location defined. It's probably a remote file." .format(song.artist, song.name, playlist.name)) common.write_to_file(root, target_path, add_standalone_to_xml_declaration=False)
def bug_200709_default_namespace(): """ >>> e = ET.Element("{default}elem") >>> s = ET.SubElement(e, "{default}elem") >>> serialize(e, default_namespace="default") # 1 '<elem xmlns="default"><elem /></elem>' >>> e = ET.Element("{default}elem") >>> s = ET.SubElement(e, "{default}elem") >>> s = ET.SubElement(e, "{not-default}elem") >>> serialize(e, default_namespace="default") # 2 '<elem xmlns="default" xmlns:ns1="not-default"><elem /><ns1:elem /></elem>' >>> e = ET.Element("{default}elem") >>> s = ET.SubElement(e, "{default}elem") >>> s = ET.SubElement(e, "elem") # unprefixed name >>> serialize(e, default_namespace="default") # 3 Traceback (most recent call last): ValueError: cannot use non-qualified names with default_namespace option """ # doesn't work with lxml.etree
def _volume(self, value, cmd='PUT'): root = etree.Element('YAMAHA_AV') root.set('cmd', cmd) system = etree.SubElement(root, 'Main_Zone') volume = etree.SubElement(system, 'Volume') level = etree.SubElement(volume, 'Lvl') if cmd == 'GET': level.text = value else: val = etree.SubElement(level, 'Val') val.text = str(value) exponent = etree.SubElement(level, 'Exp') exponent.text = '1' unit = etree.SubElement(level, 'Unit') unit.text = 'dB' tree = etree.ElementTree(root) return self._return_document(tree)
def write_xml(input): """Writes Sublime Text snippets (Plist)""" from lxml import etree completions = input["completions"][0] data = etree.Element("snippet") content = etree.SubElement(data, "content") content.text = etree.CDATA(input["completions"][0]["contents"]) tabTrigger = etree.SubElement(data, "tabTrigger") tabTrigger.text = input["completions"][0]['trigger'] scope = etree.SubElement(data, "scope") scope.text = input["scope"] if 'description' in input['completions'][0]: description = etree.SubElement(data, "description") description.text = input["completions"][0]["description"] output = etree.tostring(data, pretty_print=True, encoding="utf-8").decode('utf-8') return output
def __init__ (self, origmsg, etype, tag, **kwargs): # Add attrib and nsmap from original message. self.reply = etree.Element("rpc-reply", attrib=origmsg.attrib, nsmap=origmsg.nsmap) rpcerr = etree.SubElement(self.reply, "rpc-error") # We require a type, tag, and severity assuming error for severity. if etype in RPCERR_TYPE_ENUM: etype = RPCERR_TYPE_ENUM[etype] etree.SubElement(rpcerr, "error-type").text = str(etype) etree.SubElement(rpcerr, "error-tag").text = tag if "severity" not in kwargs: etree.SubElement(rpcerr, "error-severity").text = "error" # Now convert any other arguments to xml for key, value in kwargs.items(): key = key.replace('_', '-') etree.SubElement(rpcerr, "error-{}".format(key)).text = str(value) # This sort of sucks for humans super(RPCServerError, self).__init__(self.get_reply_msg())
def fixml_buy_now(self, ticker, quantity, limit): """Generates the FIXML for a buy order.""" fixml = Element("FIXML") fixml.set("xmlns", FIXML_NAMESPACE) order = SubElement(fixml, "Order") order.set("TmInForce", "0") # Day order order.set("Typ", "2") # Limit order.set("Side", "1") # Buy order.set("Px", "%.2f" % limit) # Limit price order.set("Acct", TRADEKING_ACCOUNT_NUMBER) instrmt = SubElement(order, "Instrmt") instrmt.set("SecTyp", "CS") # Common stock instrmt.set("Sym", ticker) ord_qty = SubElement(order, "OrdQty") ord_qty.set("Qty", str(quantity)) return tostring(fixml)
def fixml_sell_eod(self, ticker, quantity, limit): """Generates the FIXML for a sell order.""" fixml = Element("FIXML") fixml.set("xmlns", FIXML_NAMESPACE) order = SubElement(fixml, "Order") order.set("TmInForce", "7") # Market on close order.set("Typ", "2") # Limit order.set("Side", "2") # Sell order.set("Px", "%.2f" % limit) # Limit price order.set("Acct", TRADEKING_ACCOUNT_NUMBER) instrmt = SubElement(order, "Instrmt") instrmt.set("SecTyp", "CS") # Common stock instrmt.set("Sym", ticker) ord_qty = SubElement(order, "OrdQty") ord_qty.set("Qty", str(quantity)) return tostring(fixml)
def fixml_short_now(self, ticker, quantity, limit): """Generates the FIXML for a sell short order.""" fixml = Element("FIXML") fixml.set("xmlns", FIXML_NAMESPACE) order = SubElement(fixml, "Order") order.set("TmInForce", "0") # Day order order.set("Typ", "2") # Limit order.set("Side", "5") # Sell short order.set("Px", "%.2f" % limit) # Limit price order.set("Acct", TRADEKING_ACCOUNT_NUMBER) instrmt = SubElement(order, "Instrmt") instrmt.set("SecTyp", "CS") # Common stock instrmt.set("Sym", ticker) ord_qty = SubElement(order, "OrdQty") ord_qty.set("Qty", str(quantity)) return tostring(fixml)
def fixml_cover_eod(self, ticker, quantity, limit): """Generates the FIXML for a sell to cover order.""" fixml = Element("FIXML") fixml.set("xmlns", FIXML_NAMESPACE) order = SubElement(fixml, "Order") order.set("TmInForce", "7") # Market on close order.set("Typ", "2") # Limit order.set("Side", "1") # Buy order.set("Px", "%.2f" % limit) # Limit price order.set("AcctTyp", "5") # Cover order.set("Acct", TRADEKING_ACCOUNT_NUMBER) instrmt = SubElement(order, "Instrmt") instrmt.set("SecTyp", "CS") # Common stock instrmt.set("Sym", ticker) ord_qty = SubElement(order, "OrdQty") ord_qty.set("Qty", str(quantity)) return tostring(fixml)
def genAdvertNode(self, _urn_authority, _my_urn): """ Returns a etree.Element containing advertisement info for this resource :param _my_urn: URN of the resource :type _my_urn: str :param _urn_authority: URN of the authority/AM :type _urn_authority: str :rtype: Element """ # Actual resources should add some information like sliver_type r = etree.Element("node") resource_id = str(self.id) resource_available = str(self.available).lower() resource_urn = self.urn(_urn_authority) r.set("component_manager_id", _my_urn) r.set("component_name", resource_id) r.set("component_id", resource_urn) r.set("exclusive", "false") etree.SubElement(r, "available").set("now", resource_available) for sliver_type_name in self.supported_sliver_types: etree.SubElement(r, "sliver_type").set("name", sliver_type_name) return r
def depccg2xml(tree, sid): def traverse(node, spid=0): id = "s{}_sp{}".format(sid, spid) xml_node = etree.SubElement(res, "span") xml_node.set("category", str(node.cat)) xml_node.set("begin", str(node.start_of_span)) xml_node.set("end", str(node.start_of_span+len(node))) xml_node.set("id", id) if node.is_leaf: xml_node.set("terminal", "s{}_{}".format(sid, node.head_id)) else: spid, childid = traverse(node.left_child, spid+1) if not node.is_unary: spid, tmp = traverse(node.right_child, spid+1) childid += " " + tmp xml_node.set("child", childid) xml_node.set("rule", node.op_string) return spid, id res = etree.Element("ccg") res.set("id", "s{}_ccg0".format(sid)) _, id = traverse(tree) res.set("root", str(id)) return res
def to_xml(self, root_element, as_sequence=False): """ Build an xml node representation of this object under the provided root xml element @type as_sequence: bool @param as_sequence: whether to write to OpenCV sequence XML format, i.e. with "_" as element name @type root_element: lxml.etree.SubElement @param root_element: the root element to build under """ if not as_sequence: elem_name = self.__class__.__name__ else: elem_name = "_" rig_elem = etree.SubElement(root_element, elem_name) cameras_elem = etree.SubElement(rig_elem, Rig.CAMERAS_ELEMENT_TAG) if self.extrinsics is not None: self.extrinsics.to_xml(rig_elem, as_sequence=False) for camera in self.cameras: camera.to_xml(cameras_elem, as_sequence=True)
def to_xml(self, root_element, as_sequence=False): """ Build an xml node representation of this object under the provided root xml element @type as_sequence: bool @param as_sequence: whether to write to OpenCV sequence XML format, i.e. with "_" as element name @type root_element: lxml.etree.SubElement @param root_element: the root element to build under """ if not as_sequence: elem_name = self.__class__.__name__ else: elem_name = "_" rig_elem = etree.SubElement(root_element, elem_name) cameras_elem = etree.SubElement(rig_elem, MultiStereoRig.RIGS_ELEMENT_TAG) for rig in self.rigs: rig.to_xml(cameras_elem, as_sequence=True)
def to_xml(self, root_element, as_sequence=False): """ Build an xml node representation of this object under the provided root xml element @type root_element: lxml.etree.SubElement @param root_element: the root element to build under @type as_sequence: bool @param as_sequence: whether to generate XML for sequences (see OpenCV's documentation on XML/YAML persistence) """ if not as_sequence: elem_name = self.__class__.__name__ else: elem_name = "_" intrinsics_elem = etree.SubElement(root_element, elem_name) _resolution_to_xml(intrinsics_elem, self.resolution) xml.make_opencv_matrix_xml_element(intrinsics_elem, self.intrinsic_mat, "intrinsic_mat") xml.make_opencv_matrix_xml_element(intrinsics_elem, self.distortion_coeffs, "distortion_coeffs") _meta_info_to_xml(intrinsics_elem, self.error, self.time, self.calibration_image_count)
def to_xml(self, root_element, as_sequence=False): """ Build an xml node representation of this object under the provided root xml element @type root_element: lxml.etree.SubElement @param root_element: the root element to build under @type as_sequence: bool @param as_sequence: whether to generate XML for sequences (see OpenCV's documentation on XML/YAML persistence) """ if not as_sequence: elem_name = self.__class__.__name__ else: elem_name = "_" extrinsics_elem = etree.SubElement(root_element, elem_name) xml.make_opencv_matrix_xml_element(extrinsics_elem, self.rotation, "rotation") xml.make_opencv_matrix_xml_element(extrinsics_elem, self.translation, "translation") _meta_info_to_xml(extrinsics_elem, self.error, self.time, self.calibration_image_count)
def to_xml(self, root_element, as_sequence=False): """ Build an xml node representation of this object under the provided root xml element @type as_sequence: bool @param as_sequence: use sequence opencv XML notation, i.e. XML element name set to "_" @type root_element: lxml.etree.SubElement @param root_element: the root element to build under """ if not as_sequence: elem_name = self.__class__.__name__ else: elem_name = "_" camera_elem = etree.SubElement(root_element, elem_name) if self.intrinsics: self.intrinsics.to_xml(camera_elem, False) if self.extrinsics and self.extrinsics.error > 0.0: self.extrinsics.to_xml(camera_elem, False)
def recursive_options(self, element, params): for key, val in sorted(params.items()): if isinstance(val, dict): options_node = etree.SubElement( element, '{%s}%s' % (NSMAP['lticm'], 'options'), name=key, ) for key, val in sorted(val.items()): self.recursive_options(options_node, {key: val}) else: param_node = etree.SubElement( element, '{%s}%s' % (NSMAP['lticm'], 'property'), name=key, ) param_node.text = val
def to_etree(self, element): if self.category == MixedContainer.CategoryText: # Prevent exporting empty content as empty lines. if self.value.strip(): if len(element) > 0: if element[-1].tail is None: element[-1].tail = self.value else: element[-1].tail += self.value else: if element.text is None: element.text = self.value else: element.text += self.value elif self.category == MixedContainer.CategorySimple: subelement = etree_.SubElement(element, '%s' % self.name) subelement.text = self.to_etree_simple() else: # category == MixedContainer.CategoryComplex self.value.to_etree(element)
def trans_root(description,copyright,Annotation): """Some basic information about the document """ username = str(getpass.getuser()) py_version = "0.1" PMML_version = "4.3" xmlns = "http://www.dmg.org/PMML-4_2" PMML = root = Element('pmml',xmlns=xmlns, version=PMML_version) # pmml level if copyright is None: copyright = "Copyright (c) 2015 {0}".format(username) if description is None: description = "Gaussian Process Model" Header = SubElement(PMML,"header",copyright=copyright,description=description) if Annotation is not None: ET.Element(Header,"Annotation").text=Annotation return PMML
def write_linestring(pyptlist): """ This function writes a GML linestring member. Parameters ---------- pyptlist : a list of tuples List of points to be converted. A pypt is a tuple that documents the xyz coordinates of a pt e.g. (x,y,z), thus a pyptlist is a list of tuples e.g. [(x1,y1,z1), (x2,y2,z2), ...] Returns ------- linestring member : lxml Element The lxml linestring member. """ gml_LineString = Element("{" + XMLNamespaces.gml+ "}" + 'LineString') gml_posList = SubElement(gml_LineString, "{" + XMLNamespaces.gml+ "}" + 'posList') gml_posList.attrib['srsDimension'] = '3' gml_posList.text = pos_list2text(pyptlist) return gml_LineString
def write_pt(pypt): """ This function writes a GML point member. Parameters ---------- pypt : tuple of floats A pypt is a tuple that documents the xyz coordinates of a pt e.g. (x,y,z). Returns ------- point member : lxml Element The lxml point member. """ gml_Point = Element("{" + XMLNamespaces.gml+ "}" + 'Point') gml_pos = SubElement(gml_Point,"{" + XMLNamespaces.gml+ "}" + 'pos') gml_pos.attrib['srsDimension'] = "3" gml_pos.text = str(pypt[0]) + " " + str(pypt[1]) + " " + str(pypt[2]) return gml_pos
def _default_element_default(self, mapping, translation, replacing): extra_vars = {} if (replacing or self.replace) and not mapping.get("replace", True): return None, {} if not self.merge and not self.replace: return None, {} if self.merge and replacing: return None, {} e = etree.SubElement(translation, "command") e.text = mapping["negate"] for i in ('prefix', 'negate_prefix'): if i in mapping: extra_vars[i] = mapping.get(i) return None, extra_vars
def _init_element_default(self, attribute, model, other, mapping, translation): t = translation for element in mapping["container"].split("/"): try: if mapping.get("reuse", False): t = t.xpath(element)[0] else: t = etree.SubElement(t, element) except IndexError: t = etree.SubElement(t, element) key_element = mapping.get("key_element", None) if key_element: key = etree.SubElement(t, key_element) value = mapping.get("key_value", None) if value: key.text = value replace = mapping.get("replace", None) if replace and self.replace: t.set("replace", "replace") return t
def _default_element_default(self, mapping, translation, replacing): if not self.merge: return None, {} if self.merge and replacing: return None, {} t = translation for element in mapping["container"].split("."): t = etree.SubElement(t, element) key_element = mapping.get("key_element", None) if key_element: key = etree.SubElement(t, key_element) key.text = "{}".format(mapping["key_value"]) if mapping.get("delete_on_merge", True): t.set("delete", "delete") return t, {}
def _translate_leaf_default(self, attribute, model, other, mapping, translation, force=False): delete = False if not model._changed() and other and self.merge: delete = True elif not model._changed() and not force: return try: # We want to make sure we capture None value = mapping["value"] except Exception: value = None if not model._changed() else model e = translation for element in mapping["element"].split("/"): e = etree.SubElement(e, element) if delete: e.set("delete", "delete") if value is not None: e.text = "{}".format(value)
def create(self): self._project = self._data.get('project') if self._project: self._options = self._project.get('options') SubElement(self.root, 'modelVersion').text = '4.0.0' if self._options: SubElement(self.root, 'groupId').text = self._options.get('group') SubElement(self.root, 'artifactId').text = self._options.get('artifactId') SubElement(self.root, 'version').text = self._options.get('version') SubElement(self.root, 'packaging').text = 'pom' SubElement(self.root, 'description').text = self._project.get('description') SubElement(self.root, 'url').text = 'https://example.com' self.licenses = SubElement(self.root, 'licenses') self.license = SubElement(self.licenses, 'license') SubElement( self.license, 'name').text = "Apache License, Version 2.0" SubElement( self.license, 'url').text = "http://www.apache.org/licenses" self.add_framework(self._data.get('framework')) self.add_dependencies(self._data.get('dependencies'))
def add_projects_xml(project_name, project_lang, project_location, date, project_nb_files): """ Permet d'ajouter les différentes balises composant un projet qui est ajouté à la liste des projets. """ tree = etree.parse("projects.xml") projects=tree.getroot() project = etree.SubElement(projects, "project") name = etree.SubElement(project, "name") name.text = project_name language = etree.SubElement(project, "language") language.text = project_lang location = etree.SubElement(project, "location") location.text = project_location creation_date = etree.SubElement(project, "creation_date") creation_date.text = date nb_files = etree.SubElement(project, "number_files") nb_files.text = project_nb_files compil = etree.SubElement(project, "compil") compil.text = "" compil_json = etree.SubElement(project, "compil_json") compil_json.text = "" tree.write('projects.xml', pretty_print=True)
def add_query(self, pyquery): query = etree.SubElement(self.command, '{http://schemas.microsoft.com/sharepoint/soap/}query') Query = etree.SubElement(query, 'Query') if 'OrderBy' in pyquery: order = etree.SubElement(Query, 'OrderBy') for field in pyquery['OrderBy']: fieldref = etree.SubElement(order, 'FieldRef') fieldref.set('Name', field) if type(field) == tuple: fieldref.set('Name', field[0]) if field[1] == 'DESCENDING': fieldref.set('Ascending', 'FALSE') if 'GroupBy' in pyquery: order = etree.SubElement(Query, 'GroupBy') for field in pyquery['GroupBy']: fieldref = etree.SubElement(order, 'FieldRef') fieldref.set('Name', field) if 'Where' in pyquery: Query.append(pyquery['Where'])
def get_xml_element(self, root_element_name=None): """ Return XML Element node representation of the Artifact """ if root_element_name is None: clsname = self.__class__.__name__ root_element_name = clsname[0].lower() + clsname[1:] root = Element(root_element_name) members = self.__get_members() for key in members: if (key == "extension" and members[key] == "jar" and hasattr(self, "_default_extension") and getattr(self, "_default_extension") is True): continue if members[key]: item = SubElement(root, key) item.text = members[key] return root
def get_xml_element(self, root="dependency"): """Return XML Element node representation of this dependency.""" xml_root = AbstractArtifact.get_xml_element(self, root) if not self._default_scope: item = SubElement(xml_root, "scope") item.text = self.scope if not self._default_optional: item = SubElement(xml_root, "optional") item.text = self.optional if self.exclusions: exc_root = Element("exclusions") for exc in self.exclusions: exc_root.insert(len(exc_root), exc.get_xml_element()) xml_root.insert(len(root), exc_root) return xml_root
def __add_config(self, level1, level2, level3=None, content=None): if not content: raise XMvnConfigException("Provide content as keyword argument") confpath = self.__get_current_config() root = self.__init_xml() level1 = SubElement(root, level1) level2 = SubElement(level1, level2) cont_level = level2 if level3: cont_level = SubElement(level2, level3) if isinstance(content, six.string_types): cont_level.text = content elif isinstance(content, list): for elem in content: cont_level.append(elem) else: cont_level.append(content) self.__write_xml(confpath, root)