使用python递归搜索xml文档的问题

时间:2009-07-21 07:41:22

标签: 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对象返回到我的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

2 个答案:

答案 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() ...