1

Pythonを使用してMavenプロジェクト定義を解析し、バージョンを抽出しようとしています。

プロジェクト定義は次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                        http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>...</groupId>
   <artifactId>...</artifactId>
   <version>1.6.0-SNAPSHOT</version>
   ...
</project>

次を使用してバージョンを抽出できます。

root = ET.fromstring(xml)
version = root.find('./p:version', { 'p': 'http://maven.apache.org/POM/4.0.0' })
print(version.text)

prints: 1.6.0-SNAPSHOT

ただし、使用される名前空間は変更される可能性があるため、これに依存したくありません。後続のxpath式で使用する名前空間を抽出する方法はありますか?

xmlns自体が公開されているかどうかを確認するために、次のことを試しましたが、うまくいきませんでした。

root = ET.fromstring(xml)
for k in root.attrib:
    print('%s => %s' % (k, root.attrib[k]))

prints: {http://www.w3.org/2001/XMLSchema-instance}schemaLocation => http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd
4

2 に答える 2

2

残念ながら、ElementTree名前空間のサポートはかなりパッチがあります。

xml.etree.ElementTree名前空間マップを取得するには、モジュールの内部メソッドを使用する必要があります。

_, namespaces = ET._namespaces(root, 'utf8')

namespacesは、URIをキーとして、プレフィックスを値として持つdictになりました。

代わりに切り替えることができlxmlます。そのライブラリは同じElementTreeAPIを実装していますが、そのAPIを大幅に拡張しています。

たとえば、各ノードには.nsmap、キーの下のデフォルトの名前空間など、プレフィックスをURIにマップする属性が含まれていますNone

于 2013-01-16T16:37:45.163 に答える
2

ただし、使用される名前空間は変更される可能性があるため、これに依存したくありません。

名前空間のURIが変更される可能性がある、またはプレフィックスが変更される可能性があると言っていますか?それが単なるプレフィックスである場合、それは問題ではありません。重要なのは、XPathのプレフィックスが、XPathエバリュエーターに提供するプレフィックスと一致することです。そしてどちらの場合でも、名前空間の自動検出はおそらく悪い呼び出しです。誰かが次のようにそのXMLの生成を開始することを決定したとします。

<proj:project xmlns:proj="http://maven.apache.org/POM/4.0.0" 
xmlns:other="http://maven.apache.org/POM/5.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                    http://maven.apache.org/maven-v4_0_0.xsd">

これは、例と同じ名前空間でXMLを完全に表していますが、projプレフィックスが探している名前空間プレフィックスであるかどうかはわかりません。

Apacheが公式のXML形式の1つの名前空間を突然変更する可能性は低いと思いますが、本当に心配している場合は、名前空間にlocal-name()を使用するオプションが常にあるはずです。再探しています:

version = root.find('./*[local-name() = "version"]')

また、私はelementTreeライブラリに精通していませんが、これを試してXMLドキュメントの名前空間に関する情報を取得し、次のことができるかどうかを確認することができます。

namespaces = root.findall('//namespace::*')
于 2013-01-16T17:54:59.893 に答える