如何创建<;!DOCTYPE>;使用Python';芹菜

如何创建<;!DOCTYPE>;使用Python';芹菜,python,xml,elementtree,Python,Xml,Elementtree,我曾尝试在这个问题中使用答案,但无法使其起作用: 这是我的密码: import xml.etree.cElementTree as ElementTree from StringIO import StringIO s = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!DOCTYPE tmx SYSTEM \"tmx14a.dtd\" ><tmx version=\"1.4a\" />' tree = Elemen

我曾尝试在这个问题中使用答案,但无法使其起作用:

这是我的密码:

import xml.etree.cElementTree as ElementTree
from StringIO import StringIO
s = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?><!DOCTYPE tmx SYSTEM \"tmx14a.dtd\" ><tmx version=\"1.4a\" />'
tree = ElementTree.parse(StringIO(s)).getroot()
header = ElementTree.SubElement(tree,'header',{'adminlang': 'EN',})
body = ElementTree.SubElement(tree,'body')
ElementTree.ElementTree(tree).write('myfile.tmx','UTF-8')
将xml.etree.cElementTree导入为ElementTree
从StringIO导入StringIO
s=“”
tree=ElementTree.parse(StringIO(s)).getroot()
header=ElementTree.SubElement(树,'header',{'adminlang':'EN',})
body=ElementTree.SubElement(树,'body')
ElementTree.ElementTree(tree.write('myfile.tmx','UTF-8'))
当我打开生成的“myfile.tmx”文件时,它包含以下内容:

<?xml version='1.0' encoding='UTF-8'?>
<tmx version="1.4a"><header adminlang="EN" /><body /></tmx>

我错过了什么?或者,有更好的工具吗?

您可以将
write
函数上的参数设置为
False
,这样输出就不会有带有编码的xml声明,然后只需手动附加所需的头。实际上,如果您将编码设置为“utf-8”(小写),则不会添加xml声明

将xml.etree.cElementTree导入为ElementTree
tree=ElementTree.Element('tmx',{'version':'1.4a'})
子元素(树,'header',{'adminlang':'EN'})
ElementTree.SubElement(树“主体”)
将open('myfile.tmx','wb')作为f:
f、 写入(“”.encode('utf8'))
ElementTree.ElementTree(tree).write(f'utf-8')
结果文件(为可读性手动添加的换行符):


您可以使用及其
tostring
功能:

从lxml导入etree
s=”“”
""" 
tree=etree.fromstring
header=etree.SubElement(树,'header',{'adminlang':'EN'})
body=etree.SubElement(树,'body')
打印etree.tostring(树,encoding=“UTF-8”,
xml_声明=True,
漂亮的印刷品=真的,
doctype=“”)
=>


我也无法使用vanilla ElementTree找到此问题的解决方案,demalexx提出的解决方案创建了无效的XML,但被我的应用程序(DITA)拒绝。 我所建议的是一个涉及其他模块的解决方案,它非常适合我

import re
# found no way for cleanly specify a <!DOCTYPE ...> stanza in ElementTree so
# so we substitute the current <?xml ... ?> stanza with a full <?xml... + <!DOCTYPE...
new_header = '<?xml version="1.0" encoding="UTF-8" ?>\n' \
                 '<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">\n'

target_xml = re.sub(u"\<\?xml .+?>", new_header, source_xml)
with open(filename, 'w') as catalog_file:
    catalog_file.write(target_xml.encode('utf8'))
重新导入
#找不到在ElementTree中明确指定节的方法,因此

#因此,我们用一个完整的替换当前节,我使用不同的解决方案添加DOCTYPE,非常简单,非常愚蠢

import xml.etree.ElementTree as ET

with open(path_file, "w", encoding='UTF-8') as xf:
    doc_type = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE dlg:window ' \
               'PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">'
    tostring = ET.tostring(root).decode('utf-8')
    file = f"{doc_type}{tostring}"
    xf.write(file)
将xml.etree.ElementTree作为ET导入
打开时(路径_文件“w”,编码='UTF-8')为xf:
文件类型=“”
tostring=ET.tostring(根)。解码('utf-8')
file=f“{doc_type}{tostring}”
写入(文件)

您能解释一下您是如何在xml中添加新行的吗?@Learner:为了可读性,我手动添加了它。如果您想让XML包含ElementTree中的新行,请搜索如何漂亮地打印XML。这给了我一个错误
TypeError:write()参数在macOS上的python 3.6.4中必须是str,而不是bytes
。我想这是因为在同一个open()命令中,您首先以字符串形式编写,然后以二进制形式编写。@ElliottB谢谢,我更新了代码。应该可以在Python2和Python3上使用。这个解决方案不起作用,除非您手动(如前所述)输入ElementTree,这肯定不是您想要做的。下面我为这个问题提供了一个简单而愚蠢的解决方案。我得到了这个错误:
ValueError:不支持带有编码声明的Unicode字符串。请使用字节输入或不带声明的XML片段。
对于Python 3.6
etree.fromstring(s.encode(“UTF-8”)
对于Python 3.6适用。您能详细说明一下“无效XML”问题吗?@posfan12,我猜主要问题是在行的开头没有DTD,这在demalexx的答案中很容易修复。
import xml.etree.ElementTree as ET

with open(path_file, "w", encoding='UTF-8') as xf:
    doc_type = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE dlg:window ' \
               'PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">'
    tostring = ET.tostring(root).decode('utf-8')
    file = f"{doc_type}{tostring}"
    xf.write(file)