Как выводить объявления XML в Python/ElementTree

#python #xml #character-encoding #elementtree

#python #xml #кодировка символов #elementtree

Вопрос:

Я пытаюсь создать XML-файл для исходного файла ссылки word, который находится в XML. Когда я записываю в файл, он показывает только «xml_decaration=True» <?xml version='1.0' encoding='us-ascii'?> , но я хочу, чтобы он был в форме <?xml version="1.0"?> .

 from xml.etree.ElementTree import ElementTree
from xml.etree.ElementTree import Element
import xml.etree.ElementTree as ET
import uuid
from lxml import etree

root=Element('b:sources')
root.set('SelectedStyle','')
root.set('xmlns:b','http://schemas.openxmlformats.org/officeDocument/2006/bibliography')
root.set('xmlns','http://schemas.openxmlformats.org/officeDocument/2006/bibliography')
#root.attrib=('SelectedStyle'='', 'xmlns:b'='"http://schemas.openxmlformats.org/officeDocument/2006/bibliography"', 'xmlns:b'='"http://schemas.openxmlformats.org/officeDocument/2006/bibliography"','xmlns'='"http://schemas.openxmlformats.org/officeDocument/2006/bibliography"')


source=ET.SubElement(root, 'b:source')
ET.SubElement(source,'b:Tag')
ET.SubElement(source,'b:SourceType').text='Misc'
ET.SubElement(source,'b:guid').text=str(uuid.uuid1())

Author=ET.SubElement(source,'b:Author')
Author2=ET.SubElement(Author,'b:Author')
ET.SubElement(Author2,'b:Corporate').text='Norsk olje og gass'

ET.SubElement(source, 'b:Title').text='R-002'
ET.SubElement(source, 'b:Year').text='2019'
ET.SubElement(source, 'b:Month').text='10'
ET.SubElement(source, 'b:Day').text='27'


tree=ElementTree(root)

tree.write('Sources.xml', xml_declaration=True, method='xml')
  

Ответ №1:

Ответ:

При использовании xml.etree.ElementTree невозможно избежать включения атрибута encoding в объявление. Если вам вообще не нужен атрибут encoding в XML-объявлении, вам нужно использовать xml.dom.minidom not xml.etree.ElementTree .

Вот фрагмент для настройки примера:

 import xml.etree.ElementTree
a = xml.etree.ElementTree.Element('a')
tree = xml.etree.ElementTree.ElementTree(element=a)
root = tree.getroot()
  

Опустить кодировку:

 out = xml.etree.ElementTree.tostring(root, xml_declaration=True)
  
 b"<?xml version='1.0' encoding='us-ascii'?>n<a />"
  

Кодирование us-ascii :

 out = xml.etree.ElementTree.tostring(root, encoding='us-ascii', xml_declaration=True)
  
 b"<?xml version='1.0' encoding='us-ascii'?>n<a />"
  

Кодирование unicode :

 out = xml.etree.ElementTree.tostring(root, encoding='unicode', xml_declaration=True)
  
 "<?xml version='1.0' encoding='UTF-8'?>n<a />"
  

Используя minidom :

Давайте возьмем первый пример из приведенного выше с опущенной кодировкой и используем переменную out в качестве входных данных xml.dom.minidom , и вы увидите результат, который вы ищете.

 import xml.dom.minidom
dom = xml.dom.minidom.parseString(out)
dom.toxml()
  
 '<?xml version="1.0" ?><a/>'
  

Существует также симпатичный вариант печати:

 dom.toprettyxml()
  
 '<?xml version="1.0" ?>n<a/>n'
  

Примечание

Взгляните на исходный код, и вы увидите, что кодировка жестко запрограммирована в выходных данных.

         with _get_writer(file_or_filename, encoding) as (write, declared_encoding):
            if method == "xml" and (xml_declaration or
                    (xml_declaration is None and
                     declared_encoding.lower() not in ("utf-8", "us-ascii"))):
                write("<?xml version='1.0' encoding='%s'?>n" % (
                    declared_encoding,))
  

https://github.com/python/cpython/blob/550c44b89513ea96d209e2ff761302238715f082/Lib/xml/etree/ElementTree.py#L731-L736