この厄介な問題は2回目だったので、聞いてみるといいと思いました。
XMLドキュメントからElementsを取得する必要がある場合もありますが、これを行う方法は厄介です。
私が望むことを実行するPythonライブラリ、XPathを定式化するエレガントな方法、名前空間をプレフィックスに自動的に登録する方法、または組み込みのXML実装またはlxmlに隠された設定を登録して、名前空間を完全に削除する方法を知りたいです。あなたが私が欲しいものをすでに知っていない限り、明確化が続きます:)
例-ドキュメント:
<root xmlns="http://really-long-namespace.uri"
xmlns:other="http://with-ambivalent.end/#">
<other:elem/>
</root>
私は何ができますか
ElementTree APIは、XPathクエリを提供する(私が知っている)唯一の組み込みAPIです。ただし、「UNames」を使用する必要があります。これは次のようになります。/{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem
ご覧のとおり、これらは非常に冗長です。次のようにすることで、それらを短縮できます。
default_ns = "http://really-long-namespace.uri"
other_ns = "http://with-ambivalent.end/#"
doc.find("/{{{0}}}root/{{{1}}}elem".format(default_ns, other_ns))
しかし、これは{{{ugly}}}であり、≃≃≃なので壊れやすいものhttp…end/#
ですhttp…end#
。どのバリアントが使用されるかを誰が知っていますか?http…end/
http…end
また、lxmlは名前空間プレフィックスをサポートしますが、ドキュメント内のプレフィックスを使用せず、デフォルトの名前空間を処理する自動化された方法も提供しません。ドキュメントから取得するには、各名前空間の1つの要素を取得する必要があります。名前空間属性は保持されないため、これらから自動的に取得する方法もありません。
XPathクエリには名前空間に依存しない方法もありますが、冗長で醜く、組み込みの実装では使用できません。/*[local-name() = 'root']/*[local-name() = 'elem']
私がやりたいこと
以下を少し入力するだけで、上記の例を実現するためのライブラリ、オプション、または汎用XPathモーフィング関数を見つけたいと思います…</ p>
- 名前なし:
/root/elem
- 名前空間-ドキュメントのプレフィックス:
/root/other:elem
…さらに、ドキュメントのプレフィックスを使用したり、名前空間を削除したりするステートメントもあります。
さらに明確にする:私の現在のユースケースはそれと同じくらい単純ですが、将来はもっと複雑なものを使用する必要があります。
読んでくれてありがとう!
解決しました
ユーザーsamplebiasは、私の注意をpy-dom-xpathに向けました。まさに私が探していたもの。私の実際のコードは次のようになります。
#parse the document into a DOM tree
rdf_tree = xml.dom.minidom.parse("install.rdf")
#read the default namespace and prefix from the root node
context = xpath.XPathContext(rdf_tree)
name = context.findvalue("//em:id", rdf_tree)
version = context.findvalue("//em:version", rdf_tree)
#<Description/> inherits the default RDF namespace
resource_nodes = context.find("//Description/following-sibling::*", rdf_tree)
ドキュメントと一貫性があり、シンプルで名前空間を認識します。完全。