我正在尝试编写一个函数,它将获取一个xml对象,任意数量的标签,由包含标签名称,属性和属性值的元组定义(例如('tag1','id','1') )并返回最具体的节点。我的代码如下:
from xml.dom import minidom
def _search(object, *pargs):
if len(pargs) == 0:
print "length of pargs was zero"
return object
else:
print "length of pargs is %s" % len(pargs)
if pargs[0][1]:
for element in object.getElementsByTagName(pargs[0][0]):
if element.attributes[pargs[0][1]].value == pargs[0][2]:
_search(element, *pargs[1:])
else:
if object.getElementsByTagName(pargs[0][0]) == 1:
_search(element, *pargs[1:])
def main():
xmldoc = minidom.parse('./example.xml')
tag1 = ('catalog_item', 'gender', "Men's")
tag2 = ('size', 'description', 'Large')
tag3 = ('color_swatch', '', '')
args = (tag1, tag2, tag3)
node = _search(xmldoc, *args)
node.toxml()
if __name__ == "__main__":
main()
不幸的是,这似乎不起作用。这是我运行脚本时的输出:
$ ./secondsearch.py
length of pargs is 3
length of pargs is 2
length of pargs is 1
Traceback (most recent call last):
File "./secondsearch.py", line 35, in <module>
main()
File "./secondsearch.py", line 32, in main
node.toxml()
AttributeError: 'NoneType' object has no attribute 'toxml'
为什么不运行'if len(pargs)== 0'条款?如果我设法将xml对象返回到我的main方法,那么我可以将该对象传递给其他函数(可以更改节点的值,或者附加子节点等)吗?
背景:使用python自动化测试过程,环境是winxp / vista / 7上的cygwin,python版本是2.5.2。如果可能的话,我宁愿留在标准库中。
以下是工作代码:
def _search(object, *pargs):
if len(pargs) == 0:
print "length of pargs was zero"
else:
print "length of pargs is %s" % len(pargs)
for element in object.getElementsByTagName(pargs[0][0]):
if pargs[0][1]:
if element.attributes[pargs[0][1]].value == pargs[0][2]:
return _search(element, *pargs[1:])
else:
if object.getElementsByTagName(pargs[0][0]) == 1:
return _search(element, *pargs[1:])
return object
答案 0 :(得分:2)
您是否应该在递归调用_search
之前插入返回?现在的方式是,_search
的某些退出路径没有return
语句,因此它们将返回None
- 这会导致您看到的异常。
答案 1 :(得分:2)
我假设您使用http://www.eggheadcafe.com/community/aspnet/17/10084853/xml-viewer.aspx作为样本数据...
作为Vinay pointed out,您不会从递归调用_search
返回任何内容。
在你的情况下,你没有定义元素的值,而是将它传递给_search()
。
此外,如果pargs[0][1]
为空,则不会执行任何操作,但object.getElementsByTagName(pargs[0][0])
会返回多个节点...(这也是为什么您的pargs == 0情况永远不会被命中的原因.. 。)
毕竟,如果样本数据正确,则有两个匹配的节点。所以你将有一个NodeList包含:
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
并且您无法在NodeList上调用.toxml()
...