Ответ 1
Предположим, вы хотите получить значение elem2, вы можете использовать xpath, чтобы найти его.
tree = etree.parse(StringIO(htmlString), etree.HTMLParser()).getroot()
youWantValue = tree.xpath('/main/elem2')[0].text
Мне нужно проверить, существует ли определенный тег в 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
Предположим, вы хотите получить значение elem2, вы можете использовать xpath, чтобы найти его.
tree = etree.parse(StringIO(htmlString), etree.HTMLParser()).getroot()
youWantValue = tree.xpath('/main/elem2')[0].text
hasattr()
работает для этого:
if hasattr(root, 'elem1'):
foo = root.elem1
Изменить: обновленный ответ для файла образца.
Я предполагаю, что вы хотите искать каждый актив для определенных тегов. Если это так, для меня работало следующее:
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
Если ваш документ имеет тенденцию быть относительно коротким, вы можете перебирать все дочерние элементы <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