这是Modify a XML using ElementTree
的问题我现在在我的XML中使用了命名空间,并尝试在Parsing XML with namespace in Python via 'ElementTree'处理解答案并获得以下内容。
XML文件。
<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/xsd/maven-4.0.0.xsd">
<grandParent>
<parent>
<child>Sam/Astronaut</child>
</parent>
</grandParent>
</project>
查看Parsing XML with namespace in Python via 'ElementTree'后的我的python代码
import xml.etree.ElementTree as ET
spaces='xmlns':'http://maven.apache.org/POM/4.0.0','schemaLocation':'http://maven.apache.org/xsd/maven-4.0.0.xsd'}
tree = ET.parse("test.xml")
a=tree.find('parent')
for b in a.findall('child', namespaces=spaces):
if b.text.strip()=='Jay/Doctor':
print "child exists"
break
else:
ET.SubElement(a,'child').text="Jay/Doctor"
tree.write("test.xml")
我收到错误: AttributeError:&#39; NoneType&#39;对象没有属性&#39; findall&#39;
答案 0 :(得分:2)
这一行有两个问题:
a=tree.find('parent')
首先,<parent>
不是根元素的直接子元素。 <parent>
是根元素的孙子。父路径看起来像/project/grandparent/parent
。要搜索<parent>
,请尝试使用XPath表达式*/parent
或可能//parent
。
其次,<parent>
存在于默认命名空间中,因此您只能使用其简单名称来.find()
它。您需要添加命名空间。
以下是对tree.find()
的两个同等有效的调用,每个调用都应找到<parent>
节点:
a=tree.find('*/{http://maven.apache.org/POM/4.0.0}parent')
a=tree.find('*/xmlns:parent', namespaces=spaces)
接下来,对findall()
的调用需要名称空间限定符:
for b in a.findall('xmlns:child', namespaces=spaces)
第四,创建新子元素的调用需要命名空间限定符。可能有一种方法可以使用快捷方式名称,但我找不到它。我不得不使用长名称。
ET.SubElement(a,'{http://maven.apache.org/POM/4.0.0}child').text="Jay/Doctor"
最后,除非您提供默认命名空间,否则您的XML输出看起来很难看:
tree.write('test.xml', default_namespace=spaces['xmlns'])
与XML方面无关,您错误地复制了上一个问题的答案。 else
的{{1}}与for
对齐,而不与if
:
for ...
if ...
else ...