2014-07-19 51 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