l xml поиск тегов при наличии пространств имен - PullRequest
0 голосов
/ 15 февраля 2020

Я немного запутался в навигации по документу xml, который имеет пространства имен с lxml.etree. Я видел несколько потоков по этой теме c ( 1 , 2 ), а также l xml документы , но до сих пор не выяснил ответ.

xml = """<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<sbml xmlns="http://www.sbml.org/sbml/level2" level="2" metaid="metaid_0000001" version="1">
    <model id="Teusink2000_Glycolysis" metaid="metaid_0000002" name="Teusink2000_Glycolysis">
        <annotation>
        </annotation>
    </model>
</sbml>"""
from lxml import etree
utf8_parser = etree.XMLParser(encoding='utf-8')
xml = etree.fromstring(xml.encode('utf-8'), parser=utf8_parser)

Поиск элемента root, похоже, не работает, но я думаю, это потому, что это элемент root, и поэтому вам не нужно искать он

print(xml.nsmap)
print(xml.findall('sbml'))
print(xml.findall('sbml', namespaces=xml.nsmap))
print(xml.findall('sbml', namespaces={'': 'http://www.sbml.org/sbml/level2'}))

производит

{None: 'http://www.sbml.org/sbml/level2'}
[]
[]
[]

Однако поиск элемента model работает, если вы задаете ему пространство имен

print(xml.findall('model'))
print(xml.findall('model', namespaces=xml.nsmap))
print(xml.findall('model', namespaces={'': 'http://www.sbml.org/sbml/level2'}))

производит

[]
[<Element {http://www.sbml.org/sbml/level2}model at 0x2125d7c0888>]
[<Element {http://www.sbml.org/sbml/level2}model at 0x2125d7c0448>]

Но поиск элемента annotation не работает, как я ожидаю.

print(xml.findall('annotation'))
print(xml.findall('annotation', namespaces=xml.nsmap))
print(xml.findall('annotation', namespaces={'': 'http://www.sbml.org/sbml/level2'}))

производит

[]
[]
[]

Может кто-нибудь указать, что я здесь скучаю?

1 Ответ

1 голос
/ 16 февраля 2020

Ваш синтаксис неправильный. Вы можете искать только текущий уровень, используя annotation. Если вы хотите выполнить поиск по всему дереву, вам нужно использовать print(xml.findall('.//annotation', namespaces=xml.nsmap)).

print(xml.findall('.//annotation', namespaces=xml.nsmap))
# [<Element {http://www.sbml.org/sbml/level2}annotation at 0x7fbcb9a14308>]
...