2014-02-05 1 views
1

У меня возникли проблемы с получением текстового значения и узлов с использованием lxml, где XML-текст имеет пространства имен в нем. Я использовал findall ('Status'), но результат всегда пришел к нулю.lxml и xml namespaces - Использование find и findall для получения значения XML-тега

В конце концов я пришел к следующему рабочему коду .... Является ли это правильным способом использования lxml для получения значений узлов? Могу ли я улучшить это дальше?

import lxml 
xml_string='<?xml version="1.0" encoding="UTF-8"?> <SCPP:Response xmlns:SCPP="http://www.SCPP.com/XMLSchema"> <SCPP:RESP_BODY> <Seed>001335834994</Seed> </SCPP:RESP_BODY> <SCPP:RESP_HDR> <Status>00</Status> </SCPP:RESP_HDR> </SCPP:Response>' 
root = etree.fromstring(xml_string) 
nsmap = {} 
for ns in root.xpath('//namespace::*'): 
    if ns[0]: 
      nsmap[ns[0]] = ns[1] 

#Method 1 
print 'Status is ' , root.xpath('//SCPP:RESP_HDR', namespaces=nsmap)[0].find('Status').text 
print 'Seed is ' , root.xpath('//SCPP:RESP_BODY', namespaces=nsmap)[0].find('Seed').text 

#Method 2 
print 'Status is ' , root.findall('SCPP:RESP_HDR',namespaces=nsmap)[0].find('Status').text 
print 'Seed is ' , root.findall('SCPP:RESP_BODY',namespaces=nsmap)[0].find('Seed').text 

#Method 3 
print 'Status is ' , root.xpath('//SCPP:RESP_HDR', namespaces=nsmap)[0].find('Status').text 
print 'Seed is ' , root.find('SCPP:RESP_BODY',namespaces=nsmap).find('Seed').text 

ответ

1

Не обязательно строить nsmap вручную.

Replace следующие строки:

nsmap = {} 
for ns in root.xpath('//namespace::*'): 
    if ns[0]: 
      nsmap[ns[0]] = ns[1] 

с:

nsmap = root.nsmap 

Другой способ получить текст определенного элемента (с использованием XPath):

>>> root.xpath('.//SCPP:RESP_HDR/Status/text()', namespaces=nsmap)[0] 
'00' 
>>> root.xpath('.//SCPP:RESP_BODY/Seed/text()',namespaces=nsmap)[0] 
'001335834994' 
+0

Это намного чище и лучше. Я буду выполнять ваши предложения. – Guddu