2017-02-20 31 views
1

У меня есть XML-дерево, которое мне нужно искать:Python LXML - не может получить к родителю

<instance> 
    <hostName>hostname1</hostName> 
    <port enabled="true">9010</port> 
    <metadata> 
     <branch>master</branch> 
    </metadata> 
    <vipAddress>vip.address.com</vipAddress> 
</instance> 
<instance> 
    <hostName>hostname2</hostName> 
    <port enabled="true">9011</port> 
    <metadata> 
     <branch>sub_branch</branch> 
    </metadata> 
    <vipAddress>vip2.address.com</vipAddress> 
</instance> 

Я пытаюсь сделать поиск с помощью текста в отрасли затем получить элемент GrandParent и получить vipAddress и port, но когда я использую этот код, когда я пытаюсь напечатать vipAddress и port печатает все из них вместо того, что я был на самом деле ищу:

branch_name = 'master'  
for record in tree.xpath('//branch/text()'): 
    if(record == branch_name): 
    branch = record.getparent() 
    target_environment = branch.xpath('//vipAddress/text()') 
    print(target_environment) 
    target_port = branch.xpath('//port/text()') 

пример:

Если бы я должен был искать master вместо возвращения target_environment=vip.address.com и port=9011 он вернется target_environment=[vip.address.com, vip2.address.com] и port=[9010,9011]

Я уверен, что я делаю что-то простое неправильно, я просто не могу видеть, что.

ответ

1

Я не лучший в работе с XML в Python, но я вижу несколько проблем:

for record in tree.xpath('//branch/text()'): преобразует ваши ветви элементы строки, которые вы используете далее вниз по сравнению с branch_name. Строки не имеют метод getparent(), так что вы можете удалить text() из XPath и сравнить branch_name с record.text

record Как только ваш элемент, вызывая getparent() дважды на записи даст вам это прародитель элемент instance. Я уверен, что есть лучший способ сделать это, но, похоже, он работает.

.xpath('//') ищет элементы, соответствующие запросу в любом месте. Так как вы просто хотите, чтобы этот элемент был ребенком <instance>, branch.xpath('vipAddress/text()') должен делать. То же самое касается поиска target_port.

Кроме того, я думаю, что .xpath всегда возвращает список, так что даже если это все работает ваш port будет выглядеть [9011]

Собираем вместе я получаю что-то вроде:

branch_name = 'master' 
for record in tree.xpath('//branch'): 
    if(record.text == branch_name): 
    branch = record.getparent().getparent() 
    target_environment = branch.xpath('vipAddress/text()') 
    print(target_environment) 
    target_port = branch.xpath('port/text()') 
    print(target_port) 
+0

спасибо, это работает отлично! – len