2013-05-19 29 views
0

我想教自己如何解析XML。我已經閱讀了lxml教程,但他們很難理解。到目前爲止,我可以這樣做:什麼是ElementTree對象,我如何從中獲取數據?

>>> from lxml import etree 
>>> xml=etree.parse('ham.xml') 
>>> xml 
<lxml.etree._ElementTree object at 0x118de60> 

但是我怎樣才能從這個對象獲取數據?它不能像xml[0]那樣編入索引,並且它不能迭代。

更具體地說,我使用this xml file,我試圖提取,也就是說,<l>標籤是由一款包含,比如說<sp>標籤,該Barnardo屬性環繞之間的一切。

+0

嘗試:'etree.tostring(XML)' –

+0

大,這樣的作品,但我怎麼從一個特定的標籤數據? – Jono

+0

@Jono:如果你展示了'ham.xml'的內容,或者它至少是一個非常大的樣本,那麼幫助你會容易得多。 –

回答

2

這是一個ElementTree Element object

你也可以看看lxml API documentation,它有一個lxml.etree._Element page。該頁面告訴您關於您可能想知道的該類的每個屬性和方法。但是,我想先閱讀lxml.etree tutorial

但是,如果元素不能被索引,那麼它是一個空標記,並且沒有要檢索的子節點。

要找到Bernardo的所有行,需要一個XPath表達式和一個名稱空間映射。不要緊,什麼前綴您使用,只要它是一個非空字符串lxml將其映射到正確的名稱空間網址:

nsmap = {'s': 'http://www.tei-c.org/ns/1.0'} 

for line in tree.xpath('.//s:sp[@who="Barnardo"]/s:l/text()', namespaces=nsmap): 
    print line.strip() 

這在提取元素<l>所有文本中包含的<sp who="Barnardo">標籤。請注意標記名稱上的s:前綴,nsmap字典會告訴lxml要使用的名稱空間。我打印了這些沒有周圍額外的空白。

爲您的樣品文件,給出了:

>>> for line in tree.xpath('.//s:sp[@who="Barnardo"]/s:l/text()', namespaces=nsmap): 
...  print line.strip() 
... 
Who's there? 
Long live the king! 
He. 
'Tis now struck twelve; get thee to bed, Francisco. 
Have you had quiet guard? 
Well, good night. 
If you do meet Horatio and Marcellus, 
The rivals of my watch, bid them make haste. 
Say, 
What, is Horatio there? 
Welcome, Horatio: welcome, good Marcellus. 
I have seen nothing. 
Sit down awhile; 
And let us once again assail your ears, 
That are so fortified against our story 
What we have two nights seen. 
Last night of all, 
When yond same star that's westward from the pole 
Had made his course to illume that part of heaven 
Where now it burns, Marcellus and myself, 
The bell then beating one, 

In the same figure, like the king that's dead. 
Looks 'a not like the king? mark it, Horatio. 
It would be spoke to. 
See, it stalks away! 
How now, Horatio! you tremble and look pale: 
Is not this something more than fantasy? 
What think you on't? 
I think it be no other but e'en so: 
Well may it sort that this portentous figure 
Comes armed through our watch; so like the king 
That was and is the question of these wars. 
'Tis here! 
It was about to speak, when the cock crew. 
+0

太棒了,謝謝。所以我想我只需要定義一個任意的命名空間ID,然後引用它。 – Jono

1

一種方法來解析XML使用XPath。您可以撥打xpath()成員函數ElementTree,您的情況爲xml

例如,打印所有<l>元素(播放行)的XML。

subtrees = xml.xpath('//l', namespaces={'prefix': 'http://www.tei-c.org/ns/1.0'}) 
for l in subtrees: 
    print(etree.tostring(l)) 

lxml docs詳細介紹xpath功能。

如下所述,除非指定了命名空間,否則這不起作用。不幸的是,lxml不支持空名稱空間,但可以將根節點更改爲使用名稱爲prefix的名稱空間,該名稱空間也是上面使用的名稱。

<TEI xmlns:prefix="http://www.tei-c.org/ns/1.0" xml:id="sha-ham"> 
+0

除了它告訴我'子樹'是空的。我認爲這是一個名稱空間問題,但我不知道在哪裏可以找到我的名稱空間,或者如何告訴lxml它是什麼。 – Jono

+0

沒有指定名稱空間,這將不起作用。 –

+0

@MartijnPieters,你是對的,我的錯。不幸的是,XML文件使用空的名稱空間,'lxml'不支持。 – kgraney