15

当使用 Python 的 etree 创建 XML 文件时,如果我们使用 向文件写入一个空标签SubElement,我会得到:

<MyTag />

不幸的是,我们在 Fortran 中使用的 XML 解析器库不能处理这个问题,即使它是一个正确的标记。它需要看到:

<MyTag></MyTag>

有没有办法更改格式规则或 etree 中的其他内容以使其正常工作?

4

6 回答 6

18

从 Python 3.4 开始,您可以对函数方法short_empty_elements使用参数:tostring()ElementTRee.write()

>>> from xml.etree import ElementTree as ET
>>> ET.tostring(ET.fromstring('<mytag/>'), short_empty_elements=False)
b'<mytag></mytag>'

在较旧的 Python 版本(2.7 到 3.3)中,作为一种解决方法,您可以使用以下html方法写出文档:

>>> from xml.etree import ElementTree as ET
>>> ET.tostring(ET.fromstring('<mytag/>'), method='html')
'<mytag></mytag>'

ElementTree.write()方法和函数都tostring()支持method关键字参数。

在更早版本的 Python(2.6 及之前)上,您可以安装外部 ElementTree 库;1.3 版支持该关键字。

是的,这听起来有点奇怪,但html输出主要输出空元素作为开始和结束标记。一些元素最终仍然是空标签元素;特别<link/>是 ,<input/><br/>。尽管如此,还是升级您的 Fortran XML 解析器以实际解析符合标准的 XML!

于 2012-09-17T13:59:01.213 回答
5

这在 Python 3.4 中直接解决了。从那时起,write方法xml.etree.ElementTree.ElementTree具有以下short_empty_elements参数:

控制不包含内容的元素的格式。如果为 True(默认值),它们将作为单个自闭合标签发出,否则它们作为一对开始/结束标签发出。

xml.etree 文档中的更多详细信息。

于 2017-07-05T00:19:15.047 回答
3

添加一个空text是另一种选择:

etree.SubElement(parent, 'child_tag_name').text=''

但请注意,这不仅会改变文档的表示形式,还会改变文档的结构:即child_el.text,将''代替None.

哦,就像 Martijn 所说,尝试使用更好的库。

于 2013-08-11T21:22:19.213 回答
2

如果您有 sed 可用,则可以将 python 脚本的输出通过管道传输到

sed -e "s/<\([^>]*\) \/>/<\1><\/\1>/g"

它将发现任何发生<Tag />并将其替换为<Tag></Tag>

于 2013-02-11T15:17:57.217 回答
0

解释代码,ElementTree.py我使用的版本在方法中包含以下内容_write

write('<' + tagname)
...
if node.text or len(node): # this line is literal
    write('>')
    ...
    write('</%s>' % tagname)
else:
    write(' />')

为了引导程序计数器,我创建了以下内容:

class AlwaysTrueString(str):
    def __nonzero__(self): return True
true_empty_string = AlwaysTrueString()

然后我node.text = true_empty_string在那些我想要一个打开关闭标签而不是自关闭标签的 ElementTree 节点上进行设置。

通过“引导程序计数器”,我的意思是为库方法构造一组输入(在这种情况下是一个具有某种奇怪的真值测试的对象),以便库方法的调用以我希望的方式遍历其控制流图. 这非常脆弱:在新版本的库中,我的 hack 可能会失败——你可能应该将“可能”视为“几乎可以保证”。一般来说,不要打破抽象障碍。它在这里对我有用。

于 2015-06-04T16:07:34.850 回答
0

如果您有 python >=3.4,请使用short_empty_elements=False已在其他答案中显示的选项,但是:

  1. 如果您已经拥有字符串形式的 XML,并且无法触摸生成它的代码。
  2. 如果您遇到python <3.4..
  3. 如果您使用的是坚持使用自闭合标签的不同 XML 库..

然后这个工作:

 xml = "<foo/><bar/>"
 xml = re.sub(r'<([^\/]+)\/\>', r'<\1></\1>', xml)

 print(xml)

 # output will be
 # <foo></foo><bar></bar>
于 2021-03-22T20:58:04.803 回答