Python xml 复制特定子元素和所有子元素并更改其名称
Python xml duplicate a specific sub element and all sub elements and change its name
我用 xml 的子元素构建了一个完整的根树,只需要在写入文件之前复制某个部分并更改名称,例如
我尝试使用 deepcopy 但没有成功。
示例:
<main ....>
<head ....>
<element 1 .... >
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<element_1/>
</head>
</main>
新根应该是这样的
<main ....>
<head ....>
<element_1 .... >
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<element_1/>
复制后的新根应该如下所示:
<new_copy_element .... > #same data below as the one in element_1
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<new_copy_element/>
</head>
</main>
克隆之前的当前代码:
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(input_filename, parser)
root = tree.getroot()
####
for elem in root.getiterator():
if not hasattr(elem.tag, 'find'): continue # (1)
i = elem.tag.find('}')
if i >= 0:
elem.tag = elem.tag[i+1:]
objectify.deannotate(root, cleanup_namespaces=True)
def write_xml(file, element):
xmlstr = minidom.parseString(ET.tostring(element)).toprettyxml(indent=" ")
with open(file, "w") as f:
f.write(xmlstr)
f.close()
head = SubElement(root, 'head')
elem1 = SubElement(head, 'element_1')
elem1.set('xx', xx)
sub1 = SubElement(elem1, 'sub1')
sub1.set('xxx', "yyy")
for key, value in data.items():
sub11 = SubElement(sub1, 'sub1.1')
sub11.set('nnn', str(key))
.
.
elem2 = SubElement(elem1, 'elem2')
.
.
write_xml(output_filename,root)
(我需要从 elem1 复制所有数据,但在我调用 write_xml
之前或之后将其命名为 element_2
您好,您使用 deepcopy 中的副本是正确的。我创建了一个简单的 xml 示例并复制了该元素。您无需打印,只需调用您的书写功能即可。
from lxml import etree
import copy
s = """<main>
<head>
<elem1>
<sub1>Example</sub1>
</elem1>
</head>
</main>"""
file = etree.fromstring(s)
head = file.find("head")
for elem1 in file.findall(".//elem1"):
dupe = copy.deepcopy(elem1) #copy <elem1> node
dupe.tag = "new_copy_element"
head.append(dupe) #insert the new node
print(etree.tostring(file,pretty_print=True, encoding=str))
我用 xml 的子元素构建了一个完整的根树,只需要在写入文件之前复制某个部分并更改名称,例如
我尝试使用 deepcopy 但没有成功。
示例:
<main ....>
<head ....>
<element 1 .... >
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<element_1/>
</head>
</main>
新根应该是这样的
<main ....>
<head ....>
<element_1 .... >
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<element_1/>
复制后的新根应该如下所示:
<new_copy_element .... > #same data below as the one in element_1
<sub1 xxx>
<sub1.2 xxxx>
<sub1.2.1>
<sub1.2.1.1>
</sub1.2.1.1>
<sub1.2.2>
</sub1.2.2>
.
.
.
<new_copy_element/>
</head>
</main>
克隆之前的当前代码:
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(input_filename, parser)
root = tree.getroot()
####
for elem in root.getiterator():
if not hasattr(elem.tag, 'find'): continue # (1)
i = elem.tag.find('}')
if i >= 0:
elem.tag = elem.tag[i+1:]
objectify.deannotate(root, cleanup_namespaces=True)
def write_xml(file, element):
xmlstr = minidom.parseString(ET.tostring(element)).toprettyxml(indent=" ")
with open(file, "w") as f:
f.write(xmlstr)
f.close()
head = SubElement(root, 'head')
elem1 = SubElement(head, 'element_1')
elem1.set('xx', xx)
sub1 = SubElement(elem1, 'sub1')
sub1.set('xxx', "yyy")
for key, value in data.items():
sub11 = SubElement(sub1, 'sub1.1')
sub11.set('nnn', str(key))
.
.
elem2 = SubElement(elem1, 'elem2')
.
.
write_xml(output_filename,root)
(我需要从 elem1 复制所有数据,但在我调用 write_xml
之前或之后将其命名为 element_2您好,您使用 deepcopy 中的副本是正确的。我创建了一个简单的 xml 示例并复制了该元素。您无需打印,只需调用您的书写功能即可。
from lxml import etree
import copy
s = """<main>
<head>
<elem1>
<sub1>Example</sub1>
</elem1>
</head>
</main>"""
file = etree.fromstring(s)
head = file.find("head")
for elem1 in file.findall(".//elem1"):
dupe = copy.deepcopy(elem1) #copy <elem1> node
dupe.tag = "new_copy_element"
head.append(dupe) #insert the new node
print(etree.tostring(file,pretty_print=True, encoding=str))