Python で ElementTree オブジェクト構造を使用して XML を作成しようとしています。命令の処理に関しては、すべて非常にうまく機能します。ファクトリ関数 ProcessingInstruction() を使用して PI を簡単に作成できますが、要素ツリーに追加されません。手動で追加できますが、PI が通常配置されるルート要素の上に追加する方法がわかりません。誰でもこれを行う方法を知っていますか? 私はそれを行うための多くの代替方法を知っていますが、これは私が見つけることができないどこかに組み込まれている必要があるようです.
5 に答える
ライブラリを試してみてくださいlxml
。ElementTree API に従い、さらに多くの追加機能が追加されています。互換性の概要から:
ElementTree は XML の解析時にコメントと処理命令を無視しますが、etree はそれらを読み取り、それぞれ Comment または ProcessingInstruction 要素として扱います。これは、コメントがテキスト コンテンツ内にあり、Comment 要素によって分割されている場合に特に顕著です。
remove_comments
ブール値やremove_pis
キーワード引数を使用するパーサーに渡すことで、この動作を無効にすることができます。便宜上、および移植可能なコードをサポートするためetree.ETCompatXMLParser
に、デフォルトの の代わりに を使用することもできますetree.XMLParser
。ElementTree パーサーにできるだけ近いデフォルト設定を提供しようとします。
標準ライブラリにはありませんが、私の経験では、標準のElementTreeが提供しないものが必要な場合の最善の策です。
lxml API を使用すると、少し「文書化されていない」ものの、これは簡単ではありません。
トップレベルの処理命令が必要な場合は、次のように作成します。
from lxml import etree
root = etree.Element("anytagname")
root.addprevious(etree.ProcessingInstruction("anypi", "anypicontent"))
結果のドキュメントは次のようになります。
<?anypi anypicontent?>
<anytagname />
IMO はこの優れた API を際立たせる別の機能であるため、彼らは確かにこれを FAQ に追加する必要があります。
ええ、それが可能だとは思いません、ごめんなさい。ElementTreeは、DOMよりも(名前空間のない)要素中心のXML処理へのより単純なインターフェースを提供しますが、その代償として、XML情報セット全体をサポートしていません。
ルート要素(コメント、PI、Doctype、およびXML宣言)の外部に存在するコンテンツを表す明確な方法はなく、これらも解析時に破棄されます。(余談ですが、これにはDTD内部サブセットで指定されたデフォルトの属性が含まれているようです。これにより、ElementTreeは厳密に非準拠のXMLプロセッサーになります。)
write()
おそらく、PythonネイティブのElementTree実装のメソッドをサブクラス化するかモンキーパッチを適用して、 _write
_writeの前に追加のPIを呼び出す_root
ことで回避できますが、少し壊れやすい可能性があります。
完全なXML情報セットのサポートが必要な場合は、おそらくDOMを使用するのが最善です。
ElementTreeについてはよくわかりません。しかし、私が作成した「xe」というライブラリを使用して問題を解決できる可能性があります。
xe は、構造化された XML を簡単に作成できるように設計された Python クラスのセットです。さまざまな理由で長い間作業していませんでしたが、質問がある場合やバグの修正が必要な場合は、喜んでお手伝いします.
命令の処理などの基本的なサポートがあり、少し作業すれば、必要なことを実行できると思います。(処理命令を追加し始めたとき、私はそれらをよく理解していませんでした。また、それらを必要としていなかったので、コードは生半可なものです。)
見て、それが有用であるかどうかを確認してください。
http://home.avvanta.com/~steveha/xe.html
これを使用する例を次に示します。
import xe
doc = xe.XMLDoc()
prefs = xe.NestElement("prefs")
prefs.user_name = xe.TextElement("user_name")
prefs.paper = xe.NestElement("paper")
prefs.paper.width = xe.IntElement("width")
prefs.paper.height = xe.IntElement("height")
doc.root_element = prefs
prefs.user_name = "John Doe"
prefs.paper.width = 8
prefs.paper.height = 10
c = xe.Comment("this is a comment")
doc.top.append(c)
上記のコードを実行してから実行print doc
すると、次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<!-- this is a comment -->
<prefs>
<user_name>John Doe</user_name>
<paper>
<width>8</width>
<height>10</height>
</paper>
</prefs>
これに興味があり、助けが必要な場合は、お知らせください。
あなたのプロジェクトで頑張ってください。