web-dev-qa-db-ja.com

Python ElementTree default namespace?

python ElementTreeでデフォルト/接頭辞なしの名前空間を定義する方法はありますか?これはうまくいかないようです...

ns = {"":"http://maven.Apache.org/POM/4.0.0"}
pom = xml.etree.ElementTree.parse("pom.xml")
print(pom.findall("version", ns))

これもしません:

ns = {None:"http://maven.Apache.org/POM/4.0.0"}
pom = xml.etree.ElementTree.parse("pom.xml")
print(pom.findall("version", ns))

これは行いますが、すべての要素にプレフィックスを付ける必要があります。

ns = {"mvn":"http://maven.Apache.org/POM/4.0.0"}
pom = xml.etree.ElementTree.parse("pom.xml")
print(pom.findall("mvn:version", ns))

OSXでのPython 3.5の使用。

編集:答えが「いいえ」の場合でも、賞金を得ることができます:-)。私はそれを使用して多くの時間を費やした誰かからの明確な「いいえ」が欲しいだけです。

21
Robert Fraser

デフォルトの名前空間を透過的に処理する簡単な方法はありません。すでに述べたように、空の名前空間に空でない名前を割り当てることは、一般的な解決策です。

ns = {"mvn":"http://maven.Apache.org/POM/4.0.0"}
pom = xml.etree.ElementTree.parse("pom.xml")
print(pom.findall("mvn:version", ns))

ご了承ください lxml.etreeでは、空の名前空間を明示的に使用することはできません。あなたは得るでしょう:

ValueError:ElementPathでは空の名前空間接頭辞はサポートされていません


ただし、XML入力データの読み込み中に デフォルトのネームスペース定義を削除 することで、物事をより簡単にすることができます。

import xml.etree.ElementTree as ET
import re

with open("pom.xml") as f:
    xmlstring = f.read()

# Remove the default namespace definition (xmlns="http://some/namespace")
xmlstring = re.sub(r'\sxmlns="[^"]+"', '', xmlstring, count=1)

pom = ET.fromstring(xmlstring) 
print(pom.findall("version"))
23
alecxe

次のコマンドでデフォルトの名前空間を取得できます。

namespace = pom.getroot().tag.split("}")[0]+"}"

次に、要素を検索するときに、それを検索パスに追加します。

print(pom.findall(namespace+"version"))

エレガントなソリューションではありませんが、それは機能します。

1
Peppe L-G