2011-12-17 115 views
1

最快/最好的方式,我有一個看起來像這樣的XML文件:遍歷與LXML XML在Python

xml = '''<?xml version="1.0"?> 
     <root> 
      <item>text</item> 
      <item2>more text</item2> 
      <targetroot> 
       <targetcontainer> 
        <target>text i want to get</target> 
       </targetcontainer> 
       <targetcontainer> 
        <target>text i want to get</target> 
       </targetcontainer> 
      </targetroot> 
      ...more items 
     </root> 
''' 

隨着LXML我想進入電影中的元素<目標文本>。我找到了一個解決方案,但我確信有一個更好,更有效的方法來做到這一點。我的解決辦法:

target = etree.XML(xml) 

for x in target.getiterator('root'): 
    item1 = x.findtext('item') 
    for target in x.iterchildren('targetroot'): 
     for t in target.iterchildren('targetcontainer'): 
      targetText = t.findtext('target') 

雖然這個工程,因爲它給了我查看在根以及目標元素的所有元素,我有一個很難相信這是最有效的解決方案。

所以我的問題是:有沒有一種更有效的方式來訪問< target>的文本,同時停留在根循環中,因爲我還需要訪問其他元素。

回答

3

您可以使用XPath

for x in target.xpath('/root/targetroot/targetcontainer/target'): 
    print x.text 

我們要求匹配路徑所有元素。在這種情況下,路徑是/root/targetroot/targetcontainer/target,這意味着

所有<target>元素是一個<targetcontainer>元件內部,一個<targetroot>元件內部,一個<root>元件內部。另外,<root>元素應該是文檔根,因爲它前面有/,這意味着文檔的開始。

此外,您的XML文檔有兩個問題。首先,<?xml version="1.0"?>聲明應該是文檔中的第一件事 - 在本例中,它前面有一個換行符和一些空格。此外,它不是標籤,不應該關閉,因此應刪除字符串末尾的</xml>。無論如何,我已經編輯過你的問題。

編輯:這個解決方案還可以改進。你不需要通過所有的路徑 - 你可以問問文檔中的所有元素<target>。這是通過在兩個斜線之前標記名稱來完成的。既然你想所有<target>文本,獨立於他們在哪裏,這可能是一個更好的解決方案。因此,上述循環可以只是書面:

for x in target.xpath('//target'): 
    print x.text 

我想它在第一,但它並沒有奏效。然而,問題在於XML中的語法問題,而不是XPath,但我嘗試了另一個更長的路徑,並忘記重試這個問題。抱歉!無論如何,我希望我對XPath有所瞭解:)

+0

標記是我的錯誤,實際的xml有正確的語法。 xpath的東西很好用,謝謝!清潔代碼=清潔劑。 – Roland

+0

@Roland實際上,它可以變得更乾淨。我編輯了答案,看看! – brandizzi

+0

謝謝,我在閱讀xpath時想到了這一點。雖然好編輯! – Roland