Подтвердить что ты не робот

Python Lxml (objectify): проверка наличия тега

Мне нужно проверить, существует ли определенный тег в XML файле.

Например, я хочу посмотреть, существует ли тег в этом фрагменте:

 <main>
       <elem1/>
       <elem2>Hi</elem2>
       <elem3/>
       ...
 </main>

В настоящее время я использую уродливый взлом с проверкой ошибок, например:

try:
   if root.elem1.tag:
      foo = elem1
except AttributeError:
   foo = "error finding elem1"

Я также хочу настроить строку, если не удается найти node (т.е. "невозможно найти -tagname-" ).

Мне нужно проверить длинный список переменных, и я не хочу повторять код 100 раз.

Любые предложения?

Edit:

Вот отрезок фактического файла xml:

<main>
 <asset name="Virtual Dvaered Unpresence">
  <virtual/>
  <presence>
   <faction>Dvaered</faction>
   <value>-1000.000000</value>
   <range>0</range>
  </presence>
 </asset>
 <asset name="Virtual Empire Small">
  <virtual/>
  <presence>
   <faction>Empire</faction>
   <value>100.000000</value>
   <range>2</range>
  </presence>
 </asset>
</main>

Я хочу проверить, существует ли тег и, если да, получить содержимое.

Изменить править: Хорошо, я собираюсь объединить два ответа, но я могу голосовать только за них. К сожалению.

Редактировать 3: Связанный вопрос о XPath здесь: Python lxml (objectify): проблемы с Xpath

4b9b3361

Ответ 1

Предположим, вы хотите получить значение elem2, вы можете использовать xpath, чтобы найти его.

tree = etree.parse(StringIO(htmlString), etree.HTMLParser()).getroot()
youWantValue = tree.xpath('/main/elem2')[0].text

Ответ 2

hasattr() работает для этого:

if hasattr(root, 'elem1'):
    foo = root.elem1

Ответ 3

Изменить: обновленный ответ для файла образца.

Я предполагаю, что вы хотите искать каждый актив для определенных тегов. Если это так, для меня работало следующее:

import lxml.objectify

# Parse the file.
tree = lxml.objectify.parse('sample.xml')
root = tree.getroot()

# Which elements to find.
to_find = set(['presence/faction', 'presence/value', 'fake'])

# Go through each asset in the document.
for asset in root.findall('asset'):
    # Check for each element. 
    for name in to_find:
        node = asset.find(name)
        if node is not None:
            print 'Found %s, its value is %s' % (name, node)
        else:
            print 'Unable to find %s' % name

Выход был:

Found presence/value, its value is -1000.0
Found presence/faction, its value is Dvaered
Unable to find fake
Found presence/value, its value is 100.0
Found presence/faction, its value is Empire
Unable to find fake

Ответ 4

Если ваш документ имеет тенденцию быть относительно коротким, вы можете перебирать все дочерние элементы <main>, ища теги, соответствующие вашему набору имен переменных:

tree = lxml.etree.fromstring(DATA)
NAMES = set(['elem1', 'elem3'])
for node in tree.iterchildren():
    if node.tag in NAMES:
        print 'found', node.tag

Или вы можете искать каждое имя переменной по одному за раз:

for tag in ('elem1', 'elem3'):
    if tree.find(tag) is not None:
        print 'found', tag