2016-05-21 2 views
0

Я пытаюсь найти полей в файле XML SOAP с помощью LXML (3.6.0)lxml: Как искать поля без добавления пути xmlns (localhost) к каждому поисковому запросу?

... 
<soap:Body> 
<Request xmlns="http://localhost/"> 
<Test> 
<field1>hello</field1> 
<field2>world</field2> 
</Test> 
</Request> 
</soap:Body> 
... 

В этом примере я пытаюсь найти field1 и field2.

Мне нужно добавить путь к термину поиска, чтобы найти поле:

print (myroot.find(".//{http://localhost/}field1").tag) # prints 'field1' 

без него, я не нахожу ничего

print (myroot.find("field1").tag) # finds 'None' 

Есть ли другой способ поиска для тега поля (здесь field1) без указания информации о пути?

Полный пример ниже:

from lxml import etree 

example = """<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<soap:Body><Request xmlns="http://localhost/"> 
<Test><field1>hello</field1><field2>world</field2></Test> 
</Request></soap:Body></soap:Envelope> 
""" 
myroot = etree.fromstring(example) 

# this works 
print (myroot.find(".//{http://localhost/}field1").text) 
print (myroot.find(".//{http://localhost/}field2").text) 

# this fails 
print (myroot.find(".//field1").text) 
print (myroot.find("field1").text) 

Комментарий: ввод запроса SOAP дано, я не могу изменить какой-либо из него в реальном жить, чтобы сделать вещи проще.

ответ

1

Существует способ игнорировать пространство имен при выборе элемента с использованием XPath, но это не очень хорошая практика. Пространство имен существует по какой-то причине. Во всяком случае, есть более чистый способ ссылаться элемент в пространстве имен т.е. используя префикс пространства имен, который сопоставляется с URI пространства имен, вместо того, чтобы использовать фактическое пространство имен Uri каждый раз:

..... 
>>> ns = {'d': 'http://localhost/'} 
>>> print (myroot.find(".//d:field1", ns).text) 
hello 
>>> print (myroot.find(".//d:field2", ns).text) 
world 
+0

Это немного лучше, но все еще требует от меня ссылаться на 'http: // localhost /' в коде. Есть ли безопасный способ запроса 'myroot' для используемого пространства имен, чтобы код мог находить поля, если пространство имен отличается? (Объяснение: В реальном мире я разбираю журнал, полный запросов, отправленных в службу .net, а не во всех запросах есть ссылки http: // localhost /.) – 576i

+0

Проблема заключается в том, что пространство имен по умолчанию в вашем XML не объявляется на уровне корневого элемента, поэтому он не доступен непосредственно в 'myroot'. Будет ли элемент, в котором '' xmlns = ".." '' '' '' '' '' всегда называется 'Request'? – har07

+0

Я еще не уверен. У меня есть разные стороны, вызывающие службу .net, и их поведение при вызове несовместимо. Я нашел некоторые, которые также объявляют xmlsn на уровне корня и дают это имя, которое повторяется в следующих полях ... Как ' hello' – 576i