8
我想在操作XML时尽可能忠实地保留注释。在Parsed XML中保留注释(Python 2.7)
我设法保留评论,但内容得到XML转义。
#!/usr/bin/env python
# add_host_to_tomcat.py
import xml.etree.ElementTree as ET
from CommentedTreeBuilder import CommentedTreeBuilder
parser = CommentedTreeBuilder()
if __name__ == '__main__':
filename = "/opt/lucee/tomcat/conf/server.xml"
# this is the important part: use the comment-preserving parser
tree = ET.parse(filename, parser)
# get the node to add a child to
engine_node = tree.find("./Service/Engine")
# add a node: Engine.Host
host_node = ET.SubElement(
engine_node,
"Host",
name="local.mysite.com",
appBase="webapps"
)
# add a child to new node: Engine.Host.Context
ET.SubElement(
host_node,
'Context',
path="",
docBase="/path/to/doc/base"
)
tree.write('out.xml')
#!/usr/bin/env python
# CommentedTreeBuilder.py
from xml.etree import ElementTree
class CommentedTreeBuilder (ElementTree.XMLTreeBuilder):
def __init__ (self, html = 0, target = None):
ElementTree.XMLTreeBuilder.__init__(self, html, target)
self._parser.CommentHandler = self.handle_comment
def handle_comment (self, data):
self._target.start(ElementTree.Comment, {})
self._target.data(data)
self._target.end(ElementTree.Comment)
然而,像这样的评论:
<!--
EXAMPLE HOST ENTRY:
<Host name="lucee.org" appBase="webapps">
<Context path="" docBase="/var/sites/getrailo.org" />
<Alias>www.lucee.org</Alias>
<Alias>my.lucee.org</Alias>
</Host>
HOST ENTRY TEMPLATE:
<Host name="[ENTER DOMAIN NAME]" appBase="webapps">
<Context path="" docBase="[ENTER SYSTEM PATH]" />
<Alias>[ENTER DOMAIN ALIAS]</Alias>
</Host>
-->
最终成为:
<!--
EXAMPLE HOST ENTRY:
<Host name="lucee.org" appBase="webapps">
<Context path="" docBase="/var/sites/getrailo.org" />
<Alias>www.lucee.org</Alias>
<Alias>my.lucee.org</Alias>
</Host>
HOST ENTRY TEMPLATE:
<Host name="[ENTER DOMAIN NAME]" appBase="webapps">
<Context path="" docBase="[ENTER SYSTEM PATH]" />
<Alias>[ENTER DOMAIN ALIAS]</Alias>
</Host>
-->
我也试过CommentedTreeBuilder.py
self._target.data(saxutils.unescape(data))
,但它似乎并没有做任何事情。事实上,我认为问题发生在handle_commment()
之后的某个地方。
顺便提一下,这个问题类似于this。
这两个解决方案似乎都保留了评论,谢谢!但其他元素会被重新格式化(可能会重新排序属性)。我知道这对于机器可读性无关紧要,但对于我的目的(人的可读性,版本控制以及只触及明确触动的元素)而言,这很重要。 FWIW,我的原始版本恰好使其他元素保持不变(即格式化为原始版本)。这个答案确实解决了我明确的问题,所以它会得到答案奖,但我想知道是否也可以使用非注释元素格式保存。 –
就我所见,唯一被修改的东西是属性的排序和标签内的空白(如果我遗漏了任何东西,请纠正我)。你通常不应该关心后者。由于属性存储在'xml'的字典中,它们的排序在输出中是随机的。要解决这个问题,您可以使用类似于注释的解决方法,请参阅http://stackoverflow.com/q/2741480/2997179。或者用'lxml'快速测试显示,它似乎保留了属性顺序,似乎是一个可行的解决方案。无论哪种方式,我认为这值得单独的SO问题。 –
好吧..在属性之上,'xml'也放弃了处理指令标记(例如'<?xml-stylesheet href =“mystyle.css”type =“text/css”?>'),并重命名xmlns命名空间。再次,'lxml'既不。 –