Python 如何使用 xml.etree.ElementTree 编写 XML 声明

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15356641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 19:53:56  来源:igfitidea点击:

How to write XML declaration using xml.etree.ElementTree

pythonxmlelementtree

提问by Roman Alexander

I am generating an XML document in Python using an ElementTree, but the tostringfunction doesn't include an XML declarationwhen converting to plaintext.

我在 Python 中使用 生成了一个 XML 文档ElementTree,但该tostring函数在转换为纯文本时不包含XML 声明

from xml.etree.ElementTree import Element, tostring

document = Element('outer')
node = SubElement(document, 'inner')
node.NewValue = 1
print tostring(document)  # Outputs "<outer><inner /></outer>"

I need my string to include the following XML declaration:

我需要我的字符串包含以下 XML 声明:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

However, there does not seem to be any documented way of doing this.

但是,似乎没有任何记录的方法可以做到这一点。

Is there a proper method for rendering the XML declaration in an ElementTree?

是否有适当的方法来呈现 .xml 文件中的 XML 声明ElementTree

采纳答案by wrgrs

I am surprised to find that there doesn't seem to be a way with ElementTree.tostring(). You can however use ElementTree.ElementTree.write()to write your XML document to a fake file:

我惊讶地发现似乎没有办法使用ElementTree.tostring(). 但是,您可以使用ElementTree.ElementTree.write()将 XML 文档写入假文件:

from io import BytesIO
from xml.etree import ElementTree as ET

document = ET.Element('outer')
node = ET.SubElement(document, 'inner')
et = ET.ElementTree(document)

f = BytesIO()
et.write(f, encoding='utf-8', xml_declaration=True) 
print(f.getvalue())  # your XML file, encoded as UTF-8

See this question. Even then, I don't think you can get your 'standalone' attribute without writing prepending it yourself.

看到这个问题。即便如此,我不认为您可以在不自己编写的情况下获得“独立”属性。

回答by glormph

I would use lxml (see http://lxml.de/api.html).

我会使用 lxml (见http://lxml.de/api.html)。

Then you can:

然后你可以:

from lxml import etree
document = etree.Element('outer')
node = etree.SubElement(document, 'inner')
print(etree.tostring(document, xml_declaration=True))

回答by alijandro

I encounter this issue recently, after some digging of the code, I found the following code snippet is definition of function ElementTree.write

我最近遇到这个问题,经过一些代码挖掘,我发现以下代码片段是函数的定义 ElementTree.write

def write(self, file, encoding="us-ascii"):
    assert self._root is not None
    if not hasattr(file, "write"):
        file = open(file, "wb")
    if not encoding:
        encoding = "us-ascii"
    elif encoding != "utf-8" and encoding != "us-ascii":
        file.write("<?xml version='1.0' encoding='%s'?>\n" % 
     encoding)
    self._write(file, self._root, encoding, {})

So the answer is, if you need write the XML header to your file, set the encodingargument other than utf-8or us-ascii, e.g. UTF-8

所以答案是,如果您需要将 XML 标头写入文件,请设置orencoding以外的参数,例如utf-8us-asciiUTF-8

回答by Alessandro

I would use ET:

我会使用ET

try:
    from lxml import etree
    print("running with lxml.etree")
except ImportError:
    try:
        # Python 2.5
        import xml.etree.cElementTree as etree
        print("running with cElementTree on Python 2.5+")
    except ImportError:
        try:
            # Python 2.5
            import xml.etree.ElementTree as etree
            print("running with ElementTree on Python 2.5+")
        except ImportError:
            try:
                # normal cElementTree install
                import cElementTree as etree
                print("running with cElementTree")
            except ImportError:
               try:
                   # normal ElementTree install
                   import elementtree.ElementTree as etree
                   print("running with ElementTree")
               except ImportError:
                   print("Failed to import ElementTree from any known place")

document = etree.Element('outer')
node = etree.SubElement(document, 'inner')
print(etree.tostring(document, encoding='UTF-8', xml_declaration=True))

回答by Rebecca Fallon

This works if you just want to print. Getting an error when I try to send it to a file...

如果您只想打印,这有效。当我尝试将其发送到文件时出现错误...

import xml.dom.minidom as minidom
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element, SubElement, Comment, tostring

def prettify(elem):
    rough_string = ET.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="  ")

回答by Alexander O'Mara

If you include the encoding='utf8', you will get an XML header:

如果包含encoding='utf8',您将获得一个 XML 标头

xml.etree.ElementTree.tostring writes a XML encoding declaration with encoding='utf8'

xml.etree.ElementTree.tostring 使用 encoding='utf8' 编写 XML 编码声明

Sample Python code (works with Python 2 and 3):

示例 Python 代码(适用于 Python 2 和 3):

import xml.etree.ElementTree as ElementTree

tree = ElementTree.ElementTree(
    ElementTree.fromstring('<xml><test>123</test></xml>')
)
root = tree.getroot()

print('without:')
print(ElementTree.tostring(root, method='xml'))
print('')
print('with:')
print(ElementTree.tostring(root, encoding='utf8', method='xml'))

Python 2 output:

Python 2 输出:

$ python2 example.py
without:
<xml><test>123</test></xml>

with:
<?xml version='1.0' encoding='utf8'?>
<xml><test>123</test></xml>

With Python 3 you will note the bprefixindicating byte literals are returned (just like with Python 2):

在 Python 3 中,您会注意到表示返回字节文字b前缀(就像在 Python 2 中一样):

$ python3 example.py
without:
b'<xml><test>123</test></xml>'

with:
b"<?xml version='1.0' encoding='utf8'?>\n<xml><test>123</test></xml>"

回答by Andriy

The minimal working example with ElementTreepackage usage:

ElementTree包使用的最小工作示例:

import xml.etree.ElementTree as ET

document = ET.Element('outer')
node = ET.SubElement(document, 'inner')
node.text = '1'
res = ET.tostring(document, encoding='utf8', method='xml').decode()
print(res)

the output is:

输出是:

<?xml version='1.0' encoding='utf8'?>
<outer><inner>1</inner></outer>

回答by G M

Including 'standalone' in the declaration

在声明中包括“独立”

I didn't found any alternative for adding the standaloneargument in the documentation so I adapted the ET.tostingfunction to take it as an argument.

我没有找到standalone在文档中添加参数的任何替代方法,因此我调整了ET.tosting函数以将其作为参数。

from xml.etree import ElementTree as ET

# Sample
document = ET.Element('outer')
node = ET.SubElement(document, 'inner')
et = ET.ElementTree(document)

 # Function that you need   
 def tostring(element, declaration, encoding=None, method=None,):
     class dummy:
         pass
     data = []
     data.append(declaration+"\n")
     file = dummy()
     file.write = data.append
     ET.ElementTree(element).write(file, encoding, method=method)
     return "".join(data)
# Working example
xdec = """<?xml version="1.0" encoding="UTF-8" standalone="no" ?>"""    
xml = tostring(document, encoding='utf-8', declaration=xdec)

回答by Novak

Another pretty simple option is to concatenate the desired header to the string of xml like this:

另一个非常简单的选择是将所需的标头连接到 xml 字符串,如下所示:

xml = (bytes('<?xml version="1.0" encoding="UTF-8"?>\n', encoding='utf-8') + ET.tostring(root))
xml = xml.decode('utf-8')
with open('invoice.xml', 'w+') as f:
    f.write(xml)