, так как у меня возникла эта раздражающая проблема во второй раз, я подумал, что запрос поможет.
Иногда мне приходится получать элементы из документов XML, но способы сделать это неудобны.
Я хотел бы знать библиотеку python, которая делает то, что я хочу, элегантный способ формулирования моих XPath, способ автоматической регистрации пространств имен в префиксах или скрытый параметр в встроенных реализациях XML или в lxml для полного удаления пространств имен,Разъяснение следует, если вы уже не знаете, что я хочу:)
Пример документа:
<root xmlns="http://really-long-namespace.uri"
xmlns:other="http://with-ambivalent.end/#">
<other:elem/>
</root>
Что я могу сделать
API ElementTree является единственным встроенным (язнать о) предоставление запросов XPath.Но это требует, чтобы я использовал «UNames». Это выглядит так: /{http://really-long-namespace.uri}root/{http://with-ambivalent.end/#}elem
Как видите, они довольно многословны.Я могу сократить их, выполнив следующее:
default_ns = "http://really-long-namespace.uri"
other_ns = "http://with-ambivalent.end/#"
doc.find("/{{{0}}}root/{{{1}}}elem".format(default_ns, other_ns))
Но это {{{{ugly}}} и хрупкое, так как http…end/#
≃ http…end#
≃ http…end/
≃ http…end
, иКто я такой, чтобы знать, какой вариант будет использоваться?
Кроме того, lxml поддерживает префиксы пространств имен, но не использует ни те, что в документе, ни обеспечивает автоматический способ обработки пространств имен по умолчанию.Мне все равно придется получить один элемент каждого пространства имен, чтобы извлечь его из документа.Атрибуты пространства имен не сохраняются, поэтому также нет способа их автоматического извлечения из них.
Существует также способ, не зависящий от пространства имен, для запросов XPath, но он является как подробным, так и уродливым и недоступным во встроенной реализации.: /*[local-name() = 'root']/*[local-name() = 'elem']
Что я хочу сделать
Я хочу найти библиотеку, опцию или универсальную функцию XPath-morphing для достижения вышеприведенных примеров, набрав чуть больше, чем следующее…
- Пространство без имени:
/root/elem
- Префиксы пространства имен из документа:
/root/other:elem
… плюс, возможно, некоторые утверждения, которые я действительно хочу использовать префиксы документа илиУдалите пространства имен.
Дополнительные пояснения: хотя мой текущий вариант использования настолько прост, что в будущем мне придется использовать более сложные.
Спасибо за чтение!
Решено
Пользовательские выборки обратили мое внимание на py-dom-xpath ;Именно то, что я искал.Мой настоящий код теперь выглядит так:
#parse the document into a DOM tree
rdf_tree = xml.dom.minidom.parse("install.rdf")
#read the default namespace and prefix from the root node
context = xpath.XPathContext(rdf_tree)
name = context.findvalue("//em:id", rdf_tree)
version = context.findvalue("//em:version", rdf_tree)
#<Description/> inherits the default RDF namespace
resource_nodes = context.find("//Description/following-sibling::*", rdf_tree)
В соответствии с документом, простой, с учетом пространства имен;совершенны.