<p>我用python修改了pom.xml。似乎<em>etree</em>没有很好的记录。所有的东西都用了一段时间才开始工作,但现在似乎已经奏效了。</p>
<hr/>
<p>正如您在下面的代码片段中看到的,<em>Maven</em>使用名称空间<code>http://maven.apache.org/POM/4.0.0</code>。根节点中的属性<code>xmlns</code>定义默认命名空间。属性<code>xmlns:xsi</code>也定义了一个名称空间,但它只用于<code>xsi:schemaLocation</code>。</p>
<pre><code><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">
</code></pre>
<p>要在像<code>find</code>这样的方法中使用像<code>profile</code>这样的标记,还必须指定名称空间。例如,您可以编写以下代码来查找所有<code>profile</code>标记。</p>
<pre><code>import xml.etree as xml
pom = xml.parse('pom.xml')
for profile in pom.findall('//{http://maven.apache.org/POM/4.0.0}profile'):
print(repr(profile))
</code></pre>
<p>另一个重要的事情是这里。使用xml文件aboive,<code>*/</code>对于本例将有相同的结果。但它不会对其他标签起作用,比如<code>mappings</code>。由于<code>*</code>仅代表一个级别,因此<code>*/child</code>可以扩展到<code>parent/tag</code>或<code>xyz/tag</code>,但不能扩展到<code>xyz/parent/tag</code>。</p>
<hr/>
<p>我认为这是上面代码中的主要问题。必须使用<code>//</code>代替<code>*/</code>来允许任何子元素,而不是只允许直接子元素。必须指定名称空间。使用此选项,您应该可以执行类似的操作来查找所有映射:</p>
<pre><code>pom = xml.parse('pom.xml')
map = {}
for mapping in pom.findall('//{http://maven.apache.org/POM/4.0.0}mappings'
'/{http://maven.apache.org/POM/4.0.0}property'):
name = mapping.find('{http://maven.apache.org/POM/4.0.0}name').text
value = mapping.find('{http://maven.apache.org/POM/4.0.0}value').text
map[name] = value
</code></pre>
<p>但是像上面这样指定名称空间不是很好。您可以定义命名空间映射并将其作为<code>find</code>和<code>findall</code>的第二个参数:</p>
<pre><code># ...
nsmap = {'m': 'http://maven.apache.org/POM/4.0.0'}
for mapping in pom.findall('//m:mappings/m:property', nsmap):
name = mapping.find('m:name', nsmap).text
value = mapping.find('m:value', nsmap).text
map[name] = value
</code></pre>