Найти - Пользователи
Полная версия: xml.etree.ElementTree - слишком длинные пути (проблема xmlns)
Начало » Python для новичков » xml.etree.ElementTree - слишком длинные пути (проблема xmlns)
1 2
doza_and
Проблема:
разбираемый xml содержит
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0“ xmlns:l=”http://www.w3.org/1999/xlink">
поэтому установлен namespace по умолчанию.
в результате пути поиска получаются пррредлллинные:
'{http://www.gribuser.ru/xml/fictionbook/2.0}body/{http://www.gribuser.ru/xml/fictionbook/2.0}cody'
Вопрос - как сделать покороче пути для поиска элементов

я конечно обошелся:
class Turins(object):
def __init__(self,pref):
self.pref=pref
def __call__(self,ss):
return re.sub(r"([A-z0-9\-]+)",self.pref+r"\1",ss)
prf="{http://www.gribuser.ru/xml/fictionbook/2.0}"
_=Turins(prf)

root.find(_("description/title-info"))
QName делает что-то не то.
знаю что в lxml можно установить namespaces={“shortname”:"http://www.gribuser.ru/xml/fictionbook/2.0"} но у меня не lxml да и не очень это красиво все равно.

Все это выглядит очень странно. Неужели одной строчкой в начале xml можно сделать нечитаемыми все пути XPath и нет никакого пути просто описать эту гадость?

Отношу это к моему слабому знанию XPath и исходной нелюбви к дурацкому(по моему мнению) формату xml.
evilempirer
я ничего не понял зачем вы так ищите, прочитайте про xpath
doza_and
:) Я прочитал. Базовый способ который там предлагается крайне дурацкий - все элементы пути прописывать полностью квалифицированными http://www.w3.org/TR/xpath/
evilempirer
ставите // в начале пути и не надо прописывать корень, то есть вам не нужны абсолютные пути по идее.
Например так:
doc.xpath("//select[@name='fruits']/option/text()")
doza_and
Спасибо за пример. Я и так не использую полные пути, поскольку использую ноды найденные в ElementTree
>>> root.findall("./*")
[<Element {http://www.gribuser.ru/xml/fictionbook/2.0}description at 2320350>,
<Element {http://www.gribuser.ru/xml/fictionbook/2.0}body at 2320878>,
<Element {http://www.gribuser.ru/xml/fictionbook/2.0}binary at 24335a8>]
>>> root.findall("./description")
[]
Мешает именно запись в фигурных скобках - квалификация пространства имен. Хочется задать ее по умолчанию, поскольку она всегда одна и таже.
делаю так:
from xml.etree.ElementTree import ElementTree
tree = ElementTree(file="....")
root=tree.getroot()
(description,body,binary)=list(root)
tmp=description.find("{http://www.gribuser.ru/xml/fictionbook/2.0}title-info/{http://www.gribuser.ru/xml/fictionbook/2.0}author")
И я просто не могу поверить что такой длинный способ записи путей является нормальным и ни в XPath (где оно и должно быть по моему мнению) ни в ElementTree не предусмотрено короткого способа записи - очевидной установки namespace по умолчанию.
evilempirer
преведите кусок xmlки которую надо парсить
doza_and
пример:
<?xml version="1.0" encoding="utf-8" ?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
<description>
<title-info>
<genre>adv_animal</genre>
<author>
<first-name>Тигрий</first-name>
<middle-name>Георгиевич</middle-name>
<last-name>Дулькейт</last-name>
</author>
<book-title>Телецкое озеро в Легендах и былях</book-title>
</title-info>
</description>
<body>
<title>
<p>Телецкое озеро в Легендах и былях</p>
</title>
</body>
</FictionBook>
запрос:
root.findall("{http://www.gribuser.ru/xml/fictionbook/2.0}description/{http://www.gribuser.ru/xml/fictionbook/2.0}title-info/{http://www.gribuser.ru/xml/fictionbook/2.0}author/*")
dimabest
Я от модуля xml отказался когда сравнил скорость работы с lxml. На разбор небольших ответов от веб-сервиса xml тратил 0.3 сек, а lxml всего 0.003. Разница в 100 раз!

# coding: utf8

from lxml import objectify

s = """<?xml version="1.0" encoding="utf-8" ?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
<description>
<title-info>
<genre>adv_animal</genre>
<author>
<first-name>Тигрий</first-name>
<middle-name>Георгиевич</middle-name>
<last-name>Дулькейт</last-name>
</author>
<book-title>Телецкое озеро в Легендах и былях</book-title>
</title-info>
</description>
<body>
<title>
<p>Телецкое озеро в Легендах и былях</p>
</title>
</body>
</FictionBook>"""

tree = objectify.fromstring(s)
print tree.description['title-info'].genre
print tree.description['title-info'].author['first-name']
evilempirer
что мешает делать например так:
first_author_name = doc.xpath("//first_name/text()")
doza_and
ок спасибо за подсказку. Понял буду пробовать.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB