【问题标题】:How to prevent xml.ElementTree fromstring from dropping commentnode如何防止 xml.ElementTree fromstring 删除评论节点
【发布时间】:2011-07-21 12:25:29
【问题描述】:

我有以下代码片段:

    from xml.etree.ElementTree import fromstring,tostring
    mathml = fromstring(input)
    for elem in mathml.getiterator():
        elem.tag = 'm:' + elem.tag
    return tostring(mathml)

当我输入以下input:

<math>
  <a> 1 2 3 </a>  <b />
<foo>Uitleg</foo>
<!-- <bar> -->
</math>

结果:

<m:math>
  <m:a> 1 2 3 </m:a>  <m:b />
<m:foo>Uitleg</m:foo>

</m:math>

怎么会?我怎样才能保留评论?

edit:我不关心使用的确切 xml 库,但是,我应该能够对标签进行粘贴更改。不幸的是,lxml 似乎不允许这样做(而且我无法使用正确的命名空间操作)

【问题讨论】:

  • 我认为xml.etree 的当前实现不可能做到这一点。解析器从开头剥离注释节点。
  • 但是我应该能够通过使用不同的解析器来解决它? (假设有一个不丢弃 cmets)。因为 ElementTree 确实有 CommentNode,你可以创建它,所以我希望在某个地方得到一些支持。
  • 这是真的。 xml.etree 可以创建一个 Comment 节点并将其序列化为 XML,但不幸的是,其默认解析器不支持反向操作。

标签: python xml elementtree


【解决方案1】:

你不能使用xml.etree,因为它的解析器会忽略 cmets(顺便说一下,这对于 xml 解析器来说是可以接受的行为)。但是,如果您使用(兼容的)lxml 库,您可以配置parser options

from lxml import etree

parser = etree.XMLParser(remove_comments=False)
tree = etree.parse('input.xml', parser=parser)
# or alternatively set the parser as default:
# etree.set_default_parser(parser)

这将是迄今为止最简单的选择。如果你真的必须使用 xml.etree,你可以尝试连接你自己的解析器,尽管即便如此,cmets 也没有得到官方支持:看看this example(来自 xml.etree 的作者)(似乎仍然有效顺便说一下,在 python 2.7 中)

【讨论】:

  • 这似乎可行,但是,lxml 不允许我的 hacky 命名空间添加(我不想正确地做;我的 xml 文件被未知脚本后处理,我不知道添加适当命名空间的后果,因为它们目前未使用)。
  • 您也可以使用 xml.dom.minidom 来执行此操作; toxml() 和 toprettyxml() 方法都保留 cmets。 (我不能轻易使用 lxml,因为我正在编写一个最好是跨平台的附加组件,这似乎使用纯 Python 最容易做到。)
猜你喜欢
  • 2018-07-25
  • 2019-12-28
  • 1970-01-01
  • 1970-01-01
  • 2014-11-04
  • 2021-06-12
  • 2021-05-15
  • 1970-01-01
  • 2012-03-09
相关资源
最近更新 更多