2013-06-25 2 views
3

Это пример lxml doc:Как импортировать lxml xpath в пространство имен по умолчанию?

>>> regexpNS = "http://exslt.org/regular-expressions" 
>>> find = etree.XPath("//*[re:test(., '^abc$', 'i')]", 
...     namespaces={'re':regexpNS}) 

>>> root = etree.XML("<root><a>aB</a><b>aBc</b></root>") 
>>> print(find(root)[0].text) 
aBc 

Я хочу, чтобы импортировать re:test() функции по умолчанию пространства имен, так что я могу назвать это без префикса re:. Как мне это сделать? Благодаря!

ответ

3

Вы можете поместить функцию в пустой функции именах:

functionNS = etree.FunctionNamespace(None) 
functionNS['test'] = lambda context, nodes, *args: print(context, nodes, args) 

Поступая таким образом, новая test функции уже зарегистрирована с префиксом пустого пространства имен, что означает, что вы можете использовать его как это:

root.xpath("//*[test(., 'arg1', 'arg2')]") 

к сожалению function, что называется для "{http://exslt.org/regular-expressions}test" не доступен из питона, только в расширении LXML реализованного в C, поэтому вы не можете просто присвоить его functionNS['test'].

Это означает, что вы должны переопределить его в питон, чтобы назначить его на пустой функции имен ...

Если это не стоит свеч для вас, чтобы избавить вас набрав три символа, вы можете использовать этот трюк чтобы сделать re префикс пространства имен глобального:

etree.FunctionNamespace("http://exslt.org/regular-expressions").prefix = 're' 

Тогда по крайней мере, вам не нужно проходить пространства имен Сыроватскога для каждого выражения XPath.

+0

Я был очень в восторге от предложенного вами второго решения, но для меня это нарушает поведение XPath. А именно, если я создаю XPath с некоторым регулярным выражением, не передавая пространство имен (поскольку оно было настроено так, как вы упомянули), оно не работает при оценке второго раза. Это как-то путается, с ошибкой 'XPath function '{} соответствует' not found'. Любая идея почему? –

+0

Я не знаю, не могу воспроизвести это. И вы уверены, что используете 're: match (...)' всюду, а не 'match (...)' без префикса где-то? – mata

+0

Я создал MWE [здесь] (https://gist.github.com/cipri-tom/f85b246fc8a250ea4debf9178a2732b9) ... ** ИЗМЕНИТЬ **: MWE не работает сам по себе, но это экспортированный блок jupyter notebook , кажется, что он только терпит неудачу в записной книжке, когда 2 'search' находятся в разных ячейках –