2016-04-14 1 views
1

Я новичок в XML с Python и я следующая строкой XML, что я получаю в ответ от сетевого устройства:обход от одного узла в XML в другой с помощью Python

'<Response MajorVersion="1" MinorVersion="0"><Get><Configuration><OSPF MajorVersion="19" MinorVersion="2"><ProcessTable><Process><Naming><ProcessName>1</ProcessName></Naming><DefaultVRF><AreaTable><Area><Naming><AreaID>0</AreaID></Naming><Running>true</Running><NameScopeTable><NameScope><Naming><InterfaceName>Loopback0</InterfaceName></Naming><Running>true</Running><Cost>1000</Cost></NameScope><NameScope><Naming><InterfaceName>Loopback1</InterfaceName></Naming><Running>true</Running><Cost>1</Cost></NameScope><NameScope><Naming><InterfaceName>GigabitEthernet0/0/0/0</InterfaceName></Naming><Running>true</Running><Cost>1</Cost></NameScope></NameScopeTable></Area></AreaTable></DefaultVRF><Start>true</Start></Process></ProcessTable></OSPF></Configuration></Get><ResultSummary ErrorCount="0" /></Response>' 

У меня есть следующая код для извлечения информации интерфейса вместе со стоимостью интерфейса, связанной с ним. Однако я также хотел бы получить тег «AreaID», связанный с каждым интерфейсом, как часть моего словаря. Невозможно правильно перемещаться по дереву, чтобы получить значение Areaid тег:

for node in x.iter('NameScope'): 
int_name = str(node.find('Naming/InterfaceName').text) 
d[int_name] = {} 
d[int_name]['cost'] = str(node.find('Cost').text) 

Этот код дает следующий результат, когда «D» печатается:

{'GigabitEthernet0/0/0/0': {'cost': '1'}, 
'Loopback0': {'cost': '1000'}, 
'Loopback1': {'cost': '1'}} 

Я хочу что-то вроде этого на выходе:

{'GigabitEthernet0/0/0/0': {'cost': '1', 'area': 0}, 
'Loopback0': {'cost': '1000', 'area': 0}, 
'Loopback1': {'cost': '1', 'area': 0}} 

Любые предложения или модификации моего кода будут действительно оценены!

ответ

1

Я хотел бы использовать preceding обозначения:

node.xpath(".//preceding::AreaID")[0].text 

Полный код я выполняющийся:

from lxml import etree as ET 

x = ET.parse("input.xml") 
d = {} 
for node in x.iter('NameScope'): 
    int_name = str(node.find('Naming/InterfaceName').text) 
    d[int_name] = { 
     'cost': str(node.find('Cost').text), 
     'area': node.xpath(".//preceding::AreaID")[0].text 
    } 

print(d) 

распечаток:

{ 
    'Loopback0': {'cost': '1000', 'area': '0'}, 
    'Loopback1': {'cost': '1', 'area': '0'}, 
    'GigabitEthernet0/0/0/0': {'cost': '1', 'area': '0'} 
} 
+0

спасибо за Ваш ответ. Однако «x» - это объект xml.etree.ElementTree.Element. Следовательно, узел не имеет атрибута xpath. Я на Python 2.7. Кроме того, я пробовал то, что вы предложили, выполнив это: «area = str (node.find (« .// previous: AreaID ») [0] .text)», и я получил эту ошибку «SyntaxError: prefix« previous »not найденный в префиксной карте " – pypep278

+0

Кроме того, мой вход не является XML-файлом, а объектом xml.etree.ElementTree.Element. – pypep278

+1

@ pypep278 хорошо, он работает для меня, даже если я определяю строковую переменную 'data' и определяю' x' как 'x = ET.fromstring (data)'. Что произойдет, если вы используете метод 'xpath()'? – alecxe

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

  • Нет связанных вопросов^_^