python - 如何(手动)编辑元素树的xml格式
问题描述
假设我有 2 个这样的 XML 文件:
版本1.xml:
<object>
<name>boat</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>0</xmin>
<ymin>434</ymin>
<xmax>152</xmax>
<ymax>504</ymax>
</bndbox>
</object>
版本2.xml:
<object><name>boat</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox><xmin>0</xmin><ymin>434</ymin><xmax>152</xmax><ymax>504</ymax></bndbox></object>
它们之间的唯一区别是使第一个更易于阅读的空格。我试图找到如何将第二种格式转换为第一种格式。
我知道我可以使用一些解决方法,比如使用这个GitHub gist中的这个函数(我在其他场合也有):
from xml.dom import minidom
from xml.etree import ElementTree
def prettify(elem):
"""
Return a pretty-printed XML string for the Element.
"""
rough_string = ElementTree.tostring(elem, 'utf-8')
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=' ')
但我不是在寻找这个(我的需要涉及部分格式化的 XML,它不能与上述功能完美配合)。
如果我检查每个元素的文本差异,我会得到:
import xml.etree.ElementTree as ET
xml_path1 = 'path/to/version1.xml'
xml_path2 = 'path/to/version2.xml'
tree1 = ET.parse(xml_path1)
annot1 = tree1.getroot()
tree2 = ET.parse(xml_path2)
annot2 = tree2.getroot()
for elem1, elem2 in zip(annot1.iter(), annot2.iter()):
if repr(elem1.text) != repr(elem2.text):
print(elem1, repr(elem1.text), elem2, repr(elem2.text))
输出:
<Element 'object' at 0x7fb26fc2d9f8> '\n\t' <Element 'object' at 0x7fb1c4e4da48> None
<Element 'bndbox' at 0x7fb1c4e4d8b8> '\n\t\t' <Element 'bndbox' at 0x7fb1c4e4dbd8> None
如果我将指定的文本更改为相应的 version1 文本,当然,它确实将格式更改为受影响的元素,但它。
ET.dump(annot2)
输出:
<object>
<name>boat</name><pose>Unspecified</pose><truncated>0</truncated><difficult>0</difficult><bndbox>
<xmin>0</xmin><ymin>434</ymin><xmax>152</xmax><ymax>504</ymax></bndbox></object>
期望的输出当然是:
ET.dump(annot1)
输出:
<object>
<name>boat</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>0</xmin>
<ymin>434</ymin>
<xmax>152</xmax>
<ymax>504</ymax>
</bndbox>
</object>
那么,格式的处理是什么?我知道它实际上并不会影响 XML 的内容(机器认为内容与我认为的相同),但 Element Tree 保存这些信息的位置让我难以理解。
- 是否有任何(硬且可能不是有效的)方法来控制 XML 的格式?
- 为什么某些包含实际值的元素(例如
xmin
我的情况)仅显示此值并隐藏格式文本,而其他bndbox
实际封装其他子元素的元素却显示这些格式字符串?
解决方案
缺少的空格在Element.tail
(docs)中。
生成输出时,ElementTree 打印开始元素、内容、结束元素,然后是尾部。
这是格式化子树的技巧(并保留文档的其余部分):
- 使用上面的技巧漂亮地打印子树
- 转换为字符串
"\n"
在字符串中替换为"\n" + (" "*level)
wherelevel
是子树的深度。- 将带有 ETree 的字符串解析为文档,并将子树替换为新文档的根元素。
或者,您可以通过将子树包装在level
包装器元素中来创建一个新文档,漂亮地打印整个文档,然后再次找到子树。
推荐阅读
- javascript - 在对象数组中使用条件将特定字符串添加到对象数据
- linux - curl命令设置权限和下载文件
- blockly - 我们如何以块状创建树视图工具箱,如图像中的任何示例代码或需要文档指南
- blazor - Blazor 服务器中的侧边栏
- python - 我改变了速度以制作破折号,但想在这里添加一些破折号长度限制
- python - RASA - 聊天机器人 - 规格详情
- apache-poi - 如何使用 Apache XSSF 格式在 xlsx 的条件格式规则中启用“如果为真则停止”选项
- oracle - 仅当远程表可访问或oracle中有完整数据时才截断本地表
- python - 给定一个单词列表,为每个单词找到最短的唯一前缀
- flutter - 在底部导航栏颤动中删除底部阴影效果