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

问题描述:

我使用Python3.5中的xml读取编写一个xml文件。我不修改该文件。只需打开并写入。但是库修改了文件。为什么xml包在Python3中修改我的xml文件?

  1. 为什么修改?
  2. 我该如何预防?例如我只想在一个非常复杂的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号线走了。
  • <movie> - 第2行中的标签现在有属性。
  • 第7行和第11行中的<value> -tag现在具有较少的属性。
+1

通常,XML命名空间的短名称(以及它们在哪里指定)不能期望是稳定的。但是为什么你不使用'lxml'呢? – o11c

+1

'lxml'默认情况下保留了命名空间,尽管您仍然必须通过一个标志才能将XML声明置顶。 – o11c

+0

@ o11c你的意思是一个python包'lxml'?我没有注意到它。我只是在Python文档中使用'xml'作为搜索词,并找到了'ElementTree'。 – buhtz

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

为什么修改?

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

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

我该如何预防?例如我只想在一个非常复杂的xml文件中替换特定标签或其值,而不会丢失任何其他信息。

我不认为有一种方法可以防止这种情况发生。这个问题已经提出过。这里是没有答案两个非常相似的问题:

我的建议是使用lxml代替的ElementTree。使用lxml,名称空间声明将保留在原始文件中出现的位置。

1号线不见了。

该行是XML声明。建议但不是强制性的。

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