使用Python递归搜索XML文档的问题
我正在尝试写一个函数,这个函数可以接收一个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对象返回到我的主方法中,我能否把这个对象传递给其他函数(比如说可以改变节点的值,或者添加子节点等等)?
背景:我正在用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
2 个回答
你是不是应该在你调用 _search
的地方加一个 return 呢?现在这样写的话,有些从 _search
返回的路径没有 return
语句,所以它们会返回 None
,这就是你看到的那个错误的原因。
我猜你在用这个链接里的数据作为示例:http://www.eggheadcafe.com/community/aspnet/17/10084853/xml-viewer.aspx。
正如Vinay提到的,你在调用自己写的_search
函数时,没有返回任何东西。
在你的else分支中,你没有给元素定义值,但你却把它传递给了_search()
函数。
另外,如果pargs[0][1]
是空的,你也没有做任何处理,而object.getElementsByTagName(pargs[0][0])
会返回多个节点……(这也是为什么你的pargs等于0的情况从来没有被触发过……)
而且,如果这些示例数据是正确的,那么会有两个匹配的节点。所以你会得到一个包含以下内容的节点列表:
<color_swatch image="red_cardigan.jpg">Red</color_swatch>
<color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch>
而且你不能在节点列表上调用.toxml()
……