Ответ 1
Синтаксис, который вы пытаетесь использовать, является новым в ElementTree 1.3.
Такая версия поставляется с Python 2.7 или выше. Если у вас есть Python 2.6 или меньше, у вас все еще есть ElementTree 1.2.6 или меньше.
У меня возникли проблемы с использованием атрибута XPath Selector в ElementTree, который я должен выполнить в соответствии с Документация
Вот пример кода
XML
<root>
<target name="1">
<a></a>
<b></b>
</target>
<target name="2">
<a></a>
<b></b>
</target>
</root>
Python
def parse(document):
root = et.parse(document)
for target in root.findall("//target[@name='a']"):
print target._children
Я получаю следующее исключение:
expected path separator ([)
Синтаксис, который вы пытаетесь использовать, является новым в ElementTree 1.3.
Такая версия поставляется с Python 2.7 или выше. Если у вас есть Python 2.6 или меньше, у вас все еще есть ElementTree 1.2.6 или меньше.
В этом коде есть несколько проблем.
Python buildin ElementTree (ET для краткости) не имеет реальной поддержки XPATH; только ограниченное подмножество. Например, он не поддерживает выражения find-from-root, такие как //target
.
Примечание: документация
упоминает "//", но только для детей: так выражение
.//target
. //...
нет!
Существует альтернативная реализация: lxml, которая более богата. Он использует эту документацию для встроенного кода. Это не соответствует/работает.
Обозначение @name
выбирает атрибуты xml- ; выражение key=value
в теге xml.
Так что имя-значение должно быть 1 или 2, чтобы выбрать что-то в данном документе. Или можно искать цели с дочерним элементом 'a': target[a]
(no @).
Для данного документа, проанализированного с помощью встроенного ElementTree (v1.3) для root, следующий код правильный и работает:
root.findall(".//target")
Найти обе целиroot.findall(".//target/a")
Найдите два a-элементаroot.findall(".//target[a]")
Это снова находит оба элемента-мишени, поскольку оба имеют a-элементroot.findall(".//target[@name='1']")
Найдите только первую цель. Обратите внимание, что нужны кавычки вокруг 1; иначе возникает синтаксисError.root.findall(".//target[a][@name='1']")
Также действителен; найти эту цельroot.findall(".//target[@name='1']/a")
Находит только один a-элемент;...Похоже, что findall поддерживает только подмножество XPath. См. Обсуждение рассылки здесь