python lxml - 将节点从一个文件插入到具有适当结构的另一个文件中
python lxml - inserting node from one file into another file with proper structure
我对这个主题做了很多研究,我遇到的问题因我使用的方法而异。使用的文件是 XML 个文件。
我想做的是使用模板文件 EX:
<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:p="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
</Parent>
</r:root>
并将另一个文件中的节点插入父标签下的模板中。
插入文件:
<?xml version= "1.0" encoding= "iso-8859-1"?>
<Child ID="" Type="">
<Sub1>text</Sub1>
<Sub2>text</Sub2>
<Sub3>text</Sub3>
<Sub4>text</Sub4>
<Nest1>
<Sub1>text</Sub1>
<Sub2>text</Sub2>
</Nest1>
</Child>
我目前正在尝试使用 deepycopy 方法来解析文件并深度复制根目录。
lxml 方法问题:当我将节点插入父树并尝试打印出新树时,这就是输出。
<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:p="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
<Child ID="" Type=""><Sub1>text</Sub1><Sub2>text</Sub2><Sub3>text</Sub3><Sub4>text</Sub4><Nest1><Sub1>text</Sub1><Sub2>text</Sub2></Nest1></Child></Parent>
</r:root>
elementtree 方法问题:我无法使用 minidom 美化使漂亮的打印看起来正确,并且会将 r:root 变成 ns0:root。
import xml.etree.ElementTree as ET
import xml.dom.minidom as MD
def prettify(root, encoder):
rough_string = ET.tostring(root, str(encoder))
reparse = MD.parseString(rough_string)
return reparse.topprettyxml(indent=" ", newl="")
beautifulsoup 方法问题:当它用 HTML 解析时,我让它工作,但我把所有东西都小写了,我不能,无法得到 xml 解析器工作。
我所需要的只是当我插入节点时它保持漂亮的结构。
为了完成这项工作,我做错了什么或遗漏了什么?
由于您的问题被标记为 lxml
,让我们使用它。但首先请注意,在您的模板文件中有一个拼写错误:xmlns:p="./file"
可能应该是 xmlns:r="./file"
(因为您的第一个元素是 r:root
)。假设这是固定的,您可以:
from lxml import etree
temp = """<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:r="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
</Parent>
</r:root>"""
#I modified the source file a bit to differentiate the various element levels
source = """<?xml version= "1.0" encoding= "iso-8859-1"?>
<Child ID="" Type="">
<Sub1>text1</Sub1>
<Sub2>text2</Sub2>
<Sub3>text3</Sub3>
<Sub4>text4</Sub4>
<Nest1>
<NSub1>textN1</NSub1>
<NSub2>textN2</NSub2>
</Nest1>
</Child>"""
temp_doc = etree.XML(temp.encode())
source_doc = etree.XML(source.encode())
#get the elements to be inserted in the template
ins = source_doc.xpath('//Child/*')
#locate the place in the template where these elements are to be inserted
destination = temp_doc.xpath('//Parent')[0]
#now insert them
for i in reversed(ins):
destination.insert(0,i)
print(etree.tostring(temp_doc).decode())
输出:
<r:root xmlns:r="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
<Sub1>text1</Sub1>
<Sub2>text2</Sub2>
<Sub3>text3</Sub3>
<Sub4>text4</Sub4>
<Nest1>
<NSub1>textN1</NSub1>
<NSub2>textN2</NSub2>
</Nest1>
</Parent>
</r:root>
我对这个主题做了很多研究,我遇到的问题因我使用的方法而异。使用的文件是 XML 个文件。 我想做的是使用模板文件 EX:
<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:p="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
</Parent>
</r:root>
并将另一个文件中的节点插入父标签下的模板中。 插入文件:
<?xml version= "1.0" encoding= "iso-8859-1"?>
<Child ID="" Type="">
<Sub1>text</Sub1>
<Sub2>text</Sub2>
<Sub3>text</Sub3>
<Sub4>text</Sub4>
<Nest1>
<Sub1>text</Sub1>
<Sub2>text</Sub2>
</Nest1>
</Child>
我目前正在尝试使用 deepycopy 方法来解析文件并深度复制根目录。
lxml 方法问题:当我将节点插入父树并尝试打印出新树时,这就是输出。
<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:p="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
<Child ID="" Type=""><Sub1>text</Sub1><Sub2>text</Sub2><Sub3>text</Sub3><Sub4>text</Sub4><Nest1><Sub1>text</Sub1><Sub2>text</Sub2></Nest1></Child></Parent>
</r:root>
elementtree 方法问题:我无法使用 minidom 美化使漂亮的打印看起来正确,并且会将 r:root 变成 ns0:root。
import xml.etree.ElementTree as ET
import xml.dom.minidom as MD
def prettify(root, encoder):
rough_string = ET.tostring(root, str(encoder))
reparse = MD.parseString(rough_string)
return reparse.topprettyxml(indent=" ", newl="")
beautifulsoup 方法问题:当它用 HTML 解析时,我让它工作,但我把所有东西都小写了,我不能,无法得到 xml 解析器工作。
我所需要的只是当我插入节点时它保持漂亮的结构。
为了完成这项工作,我做错了什么或遗漏了什么?
由于您的问题被标记为 lxml
,让我们使用它。但首先请注意,在您的模板文件中有一个拼写错误:xmlns:p="./file"
可能应该是 xmlns:r="./file"
(因为您的第一个元素是 r:root
)。假设这是固定的,您可以:
from lxml import etree
temp = """<?xml version= "1.0" encoding= "iso-8859-1"?>
<r:root xmlns:r="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
</Parent>
</r:root>"""
#I modified the source file a bit to differentiate the various element levels
source = """<?xml version= "1.0" encoding= "iso-8859-1"?>
<Child ID="" Type="">
<Sub1>text1</Sub1>
<Sub2>text2</Sub2>
<Sub3>text3</Sub3>
<Sub4>text4</Sub4>
<Nest1>
<NSub1>textN1</NSub1>
<NSub2>textN2</NSub2>
</Nest1>
</Child>"""
temp_doc = etree.XML(temp.encode())
source_doc = etree.XML(source.encode())
#get the elements to be inserted in the template
ins = source_doc.xpath('//Child/*')
#locate the place in the template where these elements are to be inserted
destination = temp_doc.xpath('//Parent')[0]
#now insert them
for i in reversed(ins):
destination.insert(0,i)
print(etree.tostring(temp_doc).decode())
输出:
<r:root xmlns:r="./file" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Version>1</Version>
<Parent Number="">
<Sub1>text1</Sub1>
<Sub2>text2</Sub2>
<Sub3>text3</Sub3>
<Sub4>text4</Sub4>
<Nest1>
<NSub1>textN1</NSub1>
<NSub2>textN2</NSub2>
</Nest1>
</Parent>
</r:root>