13

現在 Python 2.4.3 を使用しており、アップグレードは許可されていません

更新されたファイルの XML コメントと共に、1 つ以上のタグの特定の属性の値を変更したいと考えています。

以下に示すように、XMLファイルを引数として取り、指定されたタグごとに属性を変更するPythonスクリプトを作成できました。

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 コメントが含まれているという事実を除きますが、それらは長い間なくなっており、これは悪いことです。

parse は XML 構造のみを取得すると思われますが、XML コメントは構造の一部であると考えました。また、元のドキュメントの「人間が読める」書式設定がなくなって久しいことも認識していますが、期待される動作であり、後でxmllint --formatまたは XSL を使用して書式設定する必要があることに気付きました。

4

1 に答える 1

18

これが古いことはわかっていますが、コメントを保持する方法について上記のこの回答に出くわしました。コメントをツリーに挿入する方法についてFrederik が公開した手順は、現在のバージョンの ElementTree でも機能しますが、少なくとも私の使用には必要以上の機能を備えています。XML を要素でラップしますが、これは私にとって望ましくありません。また、処理命令を保存する必要はありませんが、コメントのみを保存する必要があります。そこで、彼がサイトで提供したクラスを次のように切り詰めました。

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 の文書化されていない使用については、私は何の功績も認めていませんが、元の文書構造に影響を与えることなくコメントのみを保持することで機能します。そして、ElementTree への将来の変更 (ただし、この時点では何年も経った後ではありそうにないように思われます) がこれを破ることになることに注意してください。

于 2014-12-06T15:46:47.110 に答える