8
XMLを操作しながらコメントを可能な限り忠実に保持したいと思います。パーサされたXML(Python 2.7)のコメントを忠実に保持
私はコメントを保存することができましたが、内容は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)
#!/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')
しかし、などのようなコメント:
<!--
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'はどちらもしません。 –