2014-07-19 86 views
1

在使用ElementTree的XML配置文件時遇到問題。我想要一個簡單的方法來查找元素的文本,而不管它在XML樹中的位置。從文檔中所說的話,我應該可以用findtext()來做到這一點,但無論如何,我都會返回None。我在哪裏錯了?大家都在告訴我,XML在Python中處理起來非常簡單,但我除了麻煩之外什麼都沒有。Python ElementTree

configFileName = 'file.xml' 

def configSet (x): 
if os.path.exists(configFileName): 
    tree = ET.parse(configFileName) 
    root = tree.getroot() 
    return root.findtext(x) 

hiTemp = configSet('hiTemp') 
print hiTemp 

和XML

<configData> 
<units> 
    <temp>F</temp> 
</units> 
<pins> 
    <lights>1</lights> 
    <fan>2</fan> 
    <co2>3</co2> 
</pins> 
<events> 
    <airTemps> 
     <hiTemp>80</hiTemp> 
     <lowTemp>72</lowTemp> 
     <hiTempAlarm>84</hiTempAlarm> 
    </airTemps> 
    <CO2> 
     <co2Hi>1500</co2Hi> 
     <co2Low>1400</co2Low> 
     <co2Alarm>600</co2Alarm> 
    </CO2> 
</events> 
<settings> 
    <apikeys> 
     <prowl> 
      <apikey>None</apikey> 
     </prowl> 
    </apikeys> 
</settings> 

預期的結果

80 

實際結果

None 
+0

這可能是'os.path.exists(configFileName)'返回'False'。添加'else:raise IOError(「File not found。」)'看看是否是這種情況。 – jonrsharpe

+0

它正在找到該文件,因爲我可以返回根目錄並且它給了我父母的元素。 – jslay

回答

0

findtext需要一個完整的路徑,但是你已經給出了一個相對路徑,所以你找不到你正在尋找的元素。

您可以提供良好的XPath或修改代碼

def configSet(x): 
    if os.path.exists(configFileName): 
     tree = ET.parse(configFileName) 
     root = tree.getroot() 
     for e in root.getiterator(): 
      t = e.findtext(x) 
      if t is not None: 
       return t 

更新1:

如果你想擁有所有匹配的文本作爲一個列表,代碼是有點不同。

def configSet(x): 
    matches = [] 
    if os.path.exists(configFileName): 
     tree = ET.parse(configFileName) 
     root = tree.getroot() 
     for e in root.getiterator(): 
      t = e.findtext(x) 
      if t is not None: 
       matches.append(t) 
    return matches 
+0

這就是它!太棒了,但你能解釋一下root.getiterator中的e實際上在做什麼嗎? getiterator函數調用做什麼來允許此循環類型搜索? – jslay

+0

@ user3724263函數'getiterator'創建一個以當前元素爲根的樹型迭代器。迭代器以文檔(深度優先)順序遍歷此元素及其下的所有元素。 'e'代表迭代旅程的當前元素。 – stanleyxu2005

+0

因此,它基本上遍歷整個XML直到找到e.findtext?或者它貫​​穿整個XML只返回非None的東西? – jslay

1

你可以使用xpath來獲得你想要的元素。

return root.find('./events/airTemps/hiTemp').text

有容易遵循documentation here

+0

無論如何無需知道路徑就可以找到它嗎?我非常懷疑,這條道路會改變的永遠是一個原因,但我想你可以說,我很好奇。例如,如何設置airtemps事件之外的設置,並使用相同的函數找到引腳下燈光的值? – jslay

+0

'.//* hiTemp'應該按照文檔 – rinti

+0

@rinti工作我試過'。// * hiTemp'。如果xml在'hiTemp'之前包含'ahiTemp',etree會報告錯誤。 'lxml.etree.XMLSyntaxError:打開和結束標記不匹配:ahiTemp行12和hiTemp,行12,列29' – stanleyxu2005