2009-07-21 37 views
0

我想寫一個函數,它將採用一個xml對象,任意數量的標籤,由包含標籤名稱,屬性和屬性值的元組定義(例如('tag1' ,'id','1'))並返回可能的最具體節點。我的代碼如下:使用python遞歸搜索xml文檔的問題

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 
+1

您的代碼似乎已經被夷爲平地;你應該修復它,以便人們可以運行它。 – 2009-07-21 07:45:01

回答

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的情況下從來沒有被擊中......)

而且畢竟,如果該樣本數據是正確的,則有兩個匹配節點。所以你必須包含一個節點列表:

 <color_swatch image="red_cardigan.jpg">Red</color_swatch> 
     <color_swatch image="burgundy_cardigan.jpg">Burgundy</color_swatch> 

,你不能叫.toxml()上的節點列表...

2

你不是應該在插入您的遞歸調用前的回報_search?您現在的方式是,從_search的一些退出路徑沒有return聲明,因此它們將返回None - 這會導致您看到的異常。

+0

我不確定'你的遞歸調用前插入一個返回',特別是'前面'的意思。你能更充分地解釋嗎? – 2009-07-21 09:28:23

+0

是 - 你的說法應該是 回報_search(元素,* pargs [1:]) 而不僅僅是 _search(元素,* pargs [1:]) – 2009-07-21 09:57:22