web-dev-qa-db-ja.com

Python lxmlを使用したきれいなXMLプリンター

「醜い」XMLを含む既存のファイルから読み取り、いくつかの変更を行った後、きれいな印刷が機能しません。 etree.write(FILE_NAME, pretty_print=True)を試しました。

次のXMLがあります。

<testsuites tests="14" failures="0" disabled="0" errors="0" time="0.306" name="AllTests">
    <testsuite name="AIR" tests="14" failures="0" disabled="0" errors="0" time="0.306">
....

そして私はそれを次のように使用します:

tree = etree.parse('original.xml')
root = tree.getroot()

...    
# modifications
...

with open(FILE_NAME, "w") as f:
    tree.write(f, pretty_print=True)
21
prosseek

私にとって、この小さな問題に気づくまで、この問題は解決されませんでした。

http://lxml.de/FAQ.html#why-doesn-t-the-pretty-print-option-reformat-my-xml-output

短縮版:

次のコマンドでファイルを読み取ります。

>>> parser = etree.XMLParser(remove_blank_text=True)
>>> tree = etree.parse(filename, parser)

これにより、既存のインデントが「リセット」され、出力が独自のインデントを正しく生成できるようになります。次に、通常どおりpretty_printを実行します。

>>> tree.write(<output_file_name>, pretty_print=True)
51
woodm1979

API docs によると、lxml etreeモジュールに「write」メソッドはありません。きれいに印刷されたxml文字列をファイルに取り込むことに関して、いくつかのオプションがあります。次のようにtostringメソッドを使用できます。

f = open('doc.xml', 'w')
f.write(etree.tostring(root, pretty_print=True))
f.close()

または、入力ソースが完全ではなく、ノブやボタンを増やして出力を構成したい場合は、pythonラッパーのいずれかをtidy libに使用できます。

http://utidylib.berlios.de/

import tidy
f.write(tidy.parseString(your_xml_str, **{'output_xml':1, 'indent':1, 'input_xml':1}))

http://countergram.com/open-source/pytidylib

from tidylib import tidy_document
document, errors = tidy_document(your_xml_str, options={'output_xml':1, 'indent':1, 'input_xml':1})
f.write(document)
10
Philip Southam
fp = file('out.txt', 'w')
print(e.tree.tostring(...), file=fp)
fp.close()
6
Andreas Jung

他の回答がこれについて言及しなかった理由がわかりません。 xmlのルートを取得したい場合は、getroot()というメソッドがあります。 (少し遅れますが)ご質問にお答えできれば幸いです。

tree = et.parse(xmlFile)
root = tree.getroot()
2
elwc

Python 3で動作するように修正された答えは次のとおりです。3:

from lxml import etree
from sys import stdout
from io import BytesIO

parser = etree.XMLParser(remove_blank_text = True)
file_obj = BytesIO(text)
tree = etree.parse(file_obj, parser)
tree.write(stdout.buffer, pretty_print = True)

ここで、textは一連のバイトとしてのxmlコードです。

1