XMLを操作している間、コメントをできるだけ忠実に保存したいと思います。
コメントを保存することができましたが、コンテンツが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 に似ています。
Python 2.7および3.5でテストすると、次のコードは意図したとおりに機能するはずです。
#!/usr/bin/env python
# CommentedTreeBuilder.py
from xml.etree import ElementTree
class CommentedTreeBuilder(ElementTree.TreeBuilder):
def comment(self, data):
self.start(ElementTree.Comment, {})
self.data(data)
self.end(ElementTree.Comment)
次に、メインコードで使用します
parser = ET.XMLParser(target=CommentedTreeBuilder())
現在のものの代わりにパーサーとして。
ちなみに、コメントはlxml
で箱から出して正しく機能します。つまり、あなたはただすることができます
import lxml.etree as ET
tree = ET.parse(filename)
上記のいずれも必要ありません。
マーティンのコードは私にはうまくいきませんでした。意図したとおりに機能する以下で同じように変更しました。
import xml.etree.ElementTree as ET
class CommentedTreeBuilder(ET.XMLTreeBuilder):
def __init__(self, *args, **kwargs):
super(CommentedTreeBuilder, self).__init__(*args, **kwargs)
self._parser.CommentHandler = self.comment
def comment(self, data):
self._target.start(ET.Comment, {})
self._target.data(data)
self._target.end(ET.Comment)
これはテストです
parser=CommentedTreeBuilder()
tree = ET.parse(filename, parser)
tree.write('out.xml')
@Martinと@sukhbinderの両方の回答が私には機能しなかったようです...したがって、これをpython 3.xで実行可能な完成したソリューションとして作成しました
from xml.etree import ElementTree
string = '''<?xml version="1.0"?>
<data>
<!--Test
-->
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
</data>'''
class CommentedTreeBuilder(ElementTree.TreeBuilder):
def comment(self, data):
self.start(ElementTree.Comment, {})
self.data(data)
self.end(ElementTree.Comment)
parser = ElementTree.XMLParser(target=CommentedTreeBuilder())
tree = ElementTree.fromstring(string, parser)
print(tree.find("./*[0]").text)
# or ElementTree.parse(filename, parser)