为啥xml包在Python3中修改我的xml文件?

Posted

技术标签:

【中文标题】为啥xml包在Python3中修改我的xml文件?【英文标题】:Why does xml package modify my xml file in Python3?为什么xml包在Python3中修改我的xml文件? 【发布时间】:2018-02-09 23:01:29 【问题描述】:

我使用 Python3.5 中的 xml 库来读取写入一个 xml 文件。我不修改文件。只需打开并写入。但是库会修改文件。

    为什么要修改? 如何防止这种情况发生?例如我只是想在一个相当复杂的 xml 文件中替换特定标签或它的值,而不会丢失任何其他信息。

这是示例文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie>
    <title>Der Eisbär</title>
    <ids>
        <entry>
            <key>tmdb</key>
            <value xsi:type="xs:int" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">9321</value>
        </entry>
        <entry>
            <key>imdb</key>
            <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">tt0167132</value>
        </entry>
    </ids>
</movie>

这是代码

import xml.etree.ElementTree as ET
tree = ET.parse('x.nfo')
tree.write('y.nfo', encoding='utf-8')

xml文件变成了这个

<movie xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <title>Der Eisbär</title>
    <ids>
        <entry>
            <key>tmdb</key>
            <value xsi:type="xs:int">9321</value>
        </entry>
        <entry>
            <key>imdb</key>
            <value xsi:type="xs:string">tt0167132</value>
        </entry>
    </ids>
</movie>
第 1 行不见了。 第 2 行中的 &lt;movie&gt;-tag 现在具有属性。 第 7 行和第 11 行中的 &lt;value&gt;-tag 现在具有更少的属性。

【问题讨论】:

一般来说,不能期望 XML 命名空间的短名称(以及指定它们的位置)是稳定的。但是你为什么不使用lxml呢? lxml 在默认情况下设法保留命名空间,尽管您仍然需要传递一个标志才能将 XML 声明置于顶部。 @o11c 你的意思是一个python包lxml?我没注意到。我只是在 python 文档中使用xml 作为搜索词,然后找到了ElementTree @o11c lxml 也无济于事。它也会对代码进行一些转换。 好吧,nobody 试图保留属性顺序。所以lxml 所做的就是对它们进行排序。因此,即使它们在第一次写入时发生更改,它们在所有后续写入中都会保持一致。 【参考方案1】:

请注意,“xml 包”和“xml 库”是不明确的。标准库中有几个与 XML 相关的模块:https://docs.python.org/3/library/xml.html

为什么要修改?

ElementTree 将命名空间声明移动到根元素,并删除文档中实际未使用的命名空间。

为什么 ElementTree 会这样做?我不知道,但也许这是一种使实现更简单的方法。

如何防止这种情况发生?例如我只是想在一个相当复杂的 xml 文件中替换特定标签或它的值,而不会丢失任何其他信息。

我认为没有办法防止这种情况发生。这个问题之前已经提过了。以下是两个非常相似但没有答案的问题:

How do I parse and write XML using Python's ElementTree without moving namespaces around? Keep Existing Namespaces when overwriting XML file with ElementTree and Python

我的建议是使用 lxml 而不是 ElementTree。使用 lxml,命名空间声明将保留在它们在原始文件中出现的位置。

第 1 行不见了。

那一行是 XML 声明。建议但不是必须拥有一个。

如果您总是需要 XML 声明,请在 write() 方法调用中使用 xml_declaration=True

【讨论】:

以上是关于为啥xml包在Python3中修改我的xml文件?的主要内容,如果未能解决你的问题,请参考以下文章

java窗体程序 打包jar后 怎么动态修改xml配置信息,请问哪位大神会啊

为啥我的Android Studio里新建的drawable的XML文件里没找不到shape这个选项.

为啥我的 C# Xml 代码仅在我枚举变量 enumerable 时才有效

为啥在 Sql 中修改 Xml 值时收到 Mutator 错误

未存储 xml 首选项文件中的 defaultValue - 为啥?

为啥捆绑包在我的 asp.net mvc 项目中不起作用?