LINUX.ORG.RU

python3 xml.etree.ElementTree - хочу невозможного?

 ,


1

1

Привет всем!

Имею:

<root>
  <tagid id="10">
    <foo>
      <text>mytext</text> 
    </foo>
    <bar>
      <other>somedata</other>
    </bar>
  </tagid>
  <tagid id="20">
    <foo>
      <text>some another text</text> 
    </foo>
    <bar>
      <other>some another data</other>
    </bar>
  </tagid>
</root>

Как зная фразу: mytext, вывывести на экран значение тега-родителя: id? В моём случае цифру 10.

Спасибо!

Может можно получить значение родителя двумя и более уровнем выше, используя lxml? Пока не могу найти ответа на данный вопрос! Спасибо всем неравнодушным.

★★★★★

Последнее исправление: DALDON (всего исправлений: 4)

http://lxml.de/tutorial.html#tree-iteration
Возможно, стоит попробовать пройтись по дереву запоминая id текущего tagid. Когда дойдёшь до «mytext», будешь помнить, где был.

evilface ★★
()
Ответ на: комментарий от evilface
#!/usr/bin/env python3

from lxml import etree

xml = """<root>
  <tagid id="10">
    <foo>
      <text>mytext</text> 
    </foo>
    <bar>
      <other>somedata</other>
    </bar>
  </tagid>
  <tagid id="20">
    <foo>
      <text>some another text</text> 
    </foo>
    <bar>
      <other>some another data</other>
    </bar>
  </tagid>
</root>
"""

last_id = -1
root = etree.fromstring(xml)
for element in root.iter():
    if element.tag == 'tagid':
        last_id = element.get('id')
    elif element.tag == 'text':
        break
if last_id == -1:
    print('Not found')
else:
    print('Found in: {}'.format(last_id))


Вот, нашлось время, набросал.

evilface ★★
()
Ответ на: комментарий от evilface
#!/usr/bin/env python3

from lxml import etree

xml = """<root>
  <tagid id="10">
    <foo>
      <text>mytext</text> 
    </foo>
    <bar>
      <other>somedata</other>
    </bar>
  </tagid>
  <tagid id="20">
    <foo>
      <text>some another text</text> 
    </foo>
    <bar>
      <other>some another data</other>
    </bar>
  </tagid>
</root>"""

last_id = None
found = False
root = etree.fromstring(xml)
for element in root.iter():
    if element.tag == 'tagid':
        last_id = element.get('id')
    elif element.tag == 'text' and element.text == 'mytext':
        found = True
        break
if not found:
    print('Not found')
else:
    print('Found in: {}'.format(last_id))


Плюс исправить косяк с выбором не того элемента. )

UPD: сегодня я что-то рассеян.

evilface ★★
()
Последнее исправление: evilface (всего исправлений: 1)
Ответ на: знатный велосипед от mix_mix

А я не пользовался lxml никогда. Просто открыл доку и сделал самый простой вариант, который она предлагала, не претендуя на лучшее решение. Если твой вариант работает — ура, что, я только за.

evilface ★★
()
Ответ на: знатный велосипед от mix_mix

Я вынужден тебя поблагодарить с особой жестокостью! Я в этом совсем новый! Спасибище тебе огромное!

Долго мучался чтобы вывести на экран, сработало вот такое:

#!/usr/bin/env python
from lxml import etree
root = etree.parse('test.xml')
out = root.xpath('//tagid[foo/text = "mytext"]/@id')
print(*out)

Оно возвращает не string, а list, что в общем то логично... Пытаюсь понять как мне это превратить сразу в строку.

Спасибище!

И тебе спасибище evilface!

DALDON ★★★★★
() автор топика
Последнее исправление: DALDON (всего исправлений: 1)
Ответ на: комментарий от DALDON

Если задача состоит исключительно в выводе id, дергать python вовсе не обязательно:

xmllint --xpath 'number(//tagid[foo/text = "mytext"]/@id)' test.xml

mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

Спасибо! В моём случае лучше python. Мне надо поработать с api от ru.center. Они там возвращают то json, то xml... Надо делать post/get/put.

print(*out)

Звезда для меня загадочна. Я просто это разгуглил. :)

DALDON ★★★★★
() автор топика
Ответ на: комментарий от DALDON

Звёздочка раскрывает список в набор аргументов, так сказать. А print() принимает переменное число аргументов, в которое ты и раскрываешь список. Почитай про *args и **kwargs, если интересно.

evilface ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.