【问题标题】:How to keep comments while parsing XML using Python / ElementTree如何在使用 Python / ElementTree 解析 XML 时保留注释
【发布时间】:2011-05-27 08:40:53
【问题描述】:

目前使用 Python 2.4.3,不允许升级

我想更改一个或多个标签中给定属性的值,以及更新文件中的 XML-cmets。

我已经设法创建了一个 Python 脚本,它以 XML 文件作为参数,并为每个指定的标签更改一个属性,如下所示

def update(file, state):
    global Etree
    try:
        from elementtree import ElementTree
        print '*** using ElementTree'
    except ImportError, e:
        print '***'
        print '*** Error: Must install either ElementTree or lxml.'
        print '***'
        raise ImportError, 'must install either ElementTree or lxml'
    #end try

    doc = Etree.parse(file)
    root = doc.getroot()

    for element in root.findall('.//StateManageable'):
        element.attrib['initialState'] = state
    #end for
    doc.write(file)
#end def

这一切都很好,属性“initialState”已更新,除了我的原始 XML 也包含很多 XML cmets,但它们早已不复存在,这很糟糕。

怀疑解析只检索 XML 结构,但我认为 XML-cmets 是结构的一部分。我也意识到我的原始文档的“人类可读”格式早已不复存在,但我已经意识到这是预期的行为,之后需要使用 xmllint --format 或 XSL 进行格式化。

【问题讨论】:

  • 你打赌,当我开始创建我的第一个脚本时,我很难意识到 所有 我找到的例子中的好东西都是 2.7 的:-)

标签: python xml elementtree


【解决方案1】:

我知道这已经过时了,但我偶然发现了上面关于如何保留 cmets 的答案。 Frederik 的published instructions 关于如何将 cmets 放入树中仍然适用于当前版本的 ElementTree,但至少对我的使用而言,它比我需要的要多。它将 XML 包装在一个元素中,这对我来说是不可取的。我也不需要保留处理指令,而只需要 cmets。因此,我将他在网站上提供的课程缩减为:

import xml.etree.ElementTree as ET

class PCParser(ET.XMLTreeBuilder):

   def __init__(self):
       ET.XMLTreeBuilder.__init__(self)
       # assumes ElementTree 1.2.X
       self._parser.CommentHandler = self.handle_comment

   def handle_comment(self, data):
       self._target.start(ET.Comment, {})
       self._target.data(data)
       self._target.end(ET.Comment)

要使用它,请创建此对象的一个​​实例作为“解析器”,然后将其作为参数传递给 ElementTree.parse(),如下所示:

parser = PCParser()
self.tree = ET.parse(self.templateOut, parser=parser)

对于代码或 ElementTree 的无证使用,我没有任何功劳,但它对我来说只保留 cmets 而不会影响原始文档结构。请注意,未来对 ElementTree 的任何更改(尽管经过这么多年,目前看来不太可能)都会打破这一点。

【讨论】:

  • 我为此使用lxml 并试图让它工作。我正在导入from lxml import etree as et。我想我可以用et 替换self._parser,但不知道用什么来代替self._target。你能帮忙吗?
  • 这不适用于 python3(使用 v3.5.4 测试),因为 api 已更改。 python3解决方案见here
猜你喜欢
  • 2019-06-23
  • 2016-02-20
  • 2021-02-06
  • 2017-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多