使用 lxml python 重建 XML

Rebuild XML using lxml python

我正在尝试使用 Python 中的 lxml 基于另一个 XML 构建一个新的 XML 文件。

假设我有一个原始 XML 文件 (test_db.xml):

<?xml version="1.0" encoding="UTF-8"?>
<Test_Database Version="1.0">
 <Song FilePath="resources/test.mp3" FileSize="8911899">
  <Tags Author="YourMother" Title="Test" Genre="Singalongs" Album="Stupid Songs" />
  <Comment>4B - 6</Comment>
 </Song>
</Test_Database>

我正在使用以下内容来解析文件并将信息保存在模型中。然后我想修改信息并将其另存为单独的 XML.

from lxml import etree as ET

tree = ET.parse("resources/test_db.xml")
root = tree.getroot()

# Get main dict tag that contains all the tracks
main_dict = root.findall('Song')
self.data = main_dict

想要XML:

<?xml version="1.0" encoding="UTF-8"?>
<Test_Database Version="1.0">
 <Song FilePath="resources/test.mp3" FileSize="8911899">
  <Tags Author="YourFather" Title="NewTest" Genre="Singalongs" Album="Stupid Songs" />
  <Comment>4B - 6</Comment>
 </Song>
</Test_Database>

我一直在查看 lxml 文档,并尝试完成一些教程,但它们似乎都需要从字符串构建 XML。我不需要使用字符串,因为我已经有了实际的元素。我不应该只能够将 Song 元素添加为 root 的子元素并写入文件吗?我似乎找不到该怎么做。

我尝试过的:

root = ET.Element("root")
for obj in self.data:
    root.append(obj)
    print(ET.tostring(root, pretty_print=True))

这将所有内容打印为单个字节串,而不是分层 xml

root = ET.Element("root")
for obj in self.data:
    child = ET.SubElement(root, obj)
print(ET.tostring(root, pretty_print=True))

这显示了一个错误,即 SubElement 的参数必须是字节或 unicode。

有没有办法添加一个元素作为根的子元素?

也许不是真正的答案,但使用您的代码和 lxml.etree 直接重建 XML:

import sys, lxml
from lxml import etree

print(sys.version)
print(lxml.__version__)

xml = etree.parse('/tmp/test_db.xml')
root = xml.getroot()

# Get main dict tag that contains all the tracks
main_dict = root.findall('Song')

# create new root
root2 = etree.Element('root2')

# Add genre
genre = lxml.etree.SubElement(main_dict[0], 'Genre')
genre.text = "Country"

for obj in main_dict:
    root2.append(obj)

doc = etree.ElementTree(root2)
print(
    etree.tostring(
        doc, pretty_print=True, xml_declaration=True, encoding='utf-8'
    ).decode('utf-8')
)

输出:

3.7.7 (default, Oct 11 2020, 01:50:22) 
[Clang 12.0.0 (clang-1200.0.31.1)]
4.6.2
<?xml version='1.0' encoding='utf-8'?>
<root2><Song FilePath="resources/test.mp3" FileSize="8911899">
  <Tags Author="YourMother" Title="Test" Genre="Singalongs" Album="Stupid Songs"/>
  <Comment>4B - 6</Comment>
 <Genre>Country</Genre></Song>
</root2>