2013-05-19 3 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 будет отображать его на правильный URL пространства имен:

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

Это так здорово, спасибо. Поэтому, я думаю, мне просто нужно было определить произвольный идентификатор пространства имен и затем ссылаться на него. – Jono

1

Один из способов для разбора XML используется XPath. Вы можете вызвать функцию члена xpath() для ElementTree, в вашем случае xml.

В качестве примера можно напечатать XML для всех элементов <l> (строки пьесы).

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

Кроме того, это говорит о том, что 'subtrees' пуст. Я думаю, что это проблема с пространством имен, но я не знаю, где найти свое пространство имен или как сообщить lxml, что это такое. – Jono

+0

Это не будет работать без указания пространств имен. –

+0

@MartijnPieters, вы правы, моя ошибка. К сожалению, файл XML использует пустое пространство имен, которое 'lxml' не поддерживает. – kgraney

Смежные вопросы