Недопустимое выражение XPath, когда имя тега имеет фигурные скобки

#python #xml #xpath #lxml

#python #xml #xpath #lxml

Вопрос:

Имя тега, к которому я пытаюсь добраться, является {http://whitehatsec.com/XML-api-Vuln}description . Удобно, что каждый тег имеет префикс с этой прекрасной ссылкой на веб-сайт whitehat. К сожалению xpath , in lxml это не нравится. В настоящее время я пытаюсь vuln_root[0].xpath('//{http://whitehatsec.com/XML-api-Vuln}description') , что должно привести меня к нужному узлу. Однако lxml продолжает говорить


File "test.py", line 23, in <module>
for s in vuln_root[0].xpath('//{http://whitehatsec.com/XML-api-Vuln}description'):
File "lxml.etree.pyx", line 1509, in lxml.etree._Element.xpath (src/lxml/lxml.etree.c:50725)
File "xpath.pxi", line 318, in lxml.etree.XPathElementEvaluator.__call__ (src/lxml/lxml.etree.c:146020)
File "xpath.pxi", line 238, in lxml.etree._XPathEvaluatorBase._handle_result (src/lxml/lxml.etree.c:145028)
File "xpath.pxi", line 224, in lxml.etree._XPathEvaluatorBase._raise_eval_error (src/lxml/lxml.etree.c:144883)
lxml.etree.XPathEvalError: Invalid expression

Как я могу обойти это ужасное именование тегов в моем xpath? Спасибо

Комментарии:

1. {namespace-uri}element-name это один из способов записать имя элемента, включая его пространство имен (иногда вы также увидите их с вводом Q перед открывающей фигурной скобкой). Это то же ns-prefix:element-name самое, что и при наличии xmlns:ns-prefix='namespace-uri' объявления.

2. Для получения дополнительной информации: «Это функция, а не ошибка!» — пространства имен XML позволяют пользователям создавать составные документы, не беспокоясь о конфликтах… таким образом, вы могли бы создать документ, который включал бы как XHTML, так и XForms или что-то еще, и данные whitehat, и не беспокоиться о том, конфликтуют ли какие-либо имена тегов друг с другом. Исключительно полезно комбинировать такие вещи, как языки шаблонов / макросов XML, с другими типами документов, поскольку пространства имен сообщают вашим инструментам редактирования для ваших больших документов, что содержимое разметки является посторонними данными и должно быть оставлено в покое.

Ответ №1:

Самый простой подход здесь — просто сопоставить пространство имен.

 el.xpath('//vuln:description',
    namespaces={'vuln': 'http://whitehatsec.com/XML-api-Vuln'})
  

Комментарии:

1. Vuln потребуется {} вокруг него. Это все еще действует?

2. Нет, ему не нужно {} обходить его. Фигурные скобки являются частью синтаксиса QName .

3. Хорошо, я понимаю. Я просто был смущен, когда имя тега включало их. Я не очень хорошо знаком с xpath. Кстати, это сработало. Изначально введенные пространства имен без последних s. Спасибо за вашу помощь!

4. Кстати, это не совсем XPath — вы увидите те же обозначения и в ряде других контекстов, связанных с пространствами имен XML.