Найти - Пользователи
Полная версия: как реализовать "XPath" для данных?
Начало » Центр помощи » как реализовать "XPath" для данных?
1
esal
Мне в результате нужно написать функц для отбора данных по текстов запросу, похожему на XPath (которая может работать со списками, вложенными деревьями и еще получать атрибуты объектов внутри них). Помогите советом мне, с чего начинать хотя бы? Любые идеи и предложения ..

исходники следующие:


#!/usr/bin/env python
# -*- coding: utf-8 -*-

def path(data):
"""Эта функция позволяет работать с вложенными деревьями, списками и iterable объектами.

Так же, она позволяет получать атрибуты объектов и выбирать данные внутри них.
Все вычисления "ленивые".

>>> class Meta(object):
... def __init__(self, value):
... self.value = value
... self.dvalue = dict(a = value)
... def __repr__(self):
... return u'<meta: %s>' % self.value
>>>
>>> data = {
... 'voices': 100500,
... 'items': [
... {
... 'id': 1,
... 'name': 'User1',
... 'meta': Meta(123),
... },
... {
... 'id': 2,
... 'name': 'User2',
... 'meta': Meta(456),
... },
... 'text item',
... {
... 'name': 'Without id',
... },
... ]
... }
>>> hasattr(path(data).items, '__iter__')
True
>>> list(path(data).voices)
[100500]
>>> list(path(data).items)
[{'meta': <meta: 123>, 'id': 1, 'name': 'User1'}, {'meta': <meta: 456>, 'id': 2, 'name': 'User2'}, 'text item', {'name': 'Without id'}]
>>> list(path(data).items.id)
[1, 2]
>>> list(path(data).items.meta['value'])
[123, 456]
>>> list(path(data).items.meta['dvalue'].a)
[123, 456]
>>> list(path(data).items[2:].name)
['Without id']
>>> items = path(data).items
>>> list(items.name)
['User1', 'User2', 'Without id']
>>> list(items.id)
[1, 2]
>>> # так же должно работать со списком данных
>>> list(path([data, data]).items.meta['dvalue'].a)
[123, 456, 123, 456]
>>> # и с обычными объектами тоже
>>> list(path(Meta(123))['dvalue'].a)
[123]
>>> # и с генераторами
>>> list(path(Meta(x) for x in xrange(10))['dvalue'].a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
"""
pass

if __name__ == '__main__':
import doctest
doctest.testmod()
doza_and
Мне кажется надо прежде всего начать с четкой спецификации требований. У вас насколько я понял не используются * и прочие кванторы - это так задумано что используется только сравнение? Произвольные питоновские объекты в отличии от XPath не образуют дерева - или вы потребуете что это обязательно будет дерево?
Похожие штуки я делал при отображении состава объекта в GUI. Моя реализация близка к http://www.opentradingsystem.com/TradingPlatform/OTS_Python_Object_Browser_.html
Я бы реализовал как рекурсивный генератор
def ListVal(tree,keyList):
if not hasattr(tree,"keys"):
yield tree
return
for k,el in tree.iteritems():
if k==keyList[0]:
for res in ListVal(el,keyList[1:])
yield res
Случай обобщения на классы и списки приведен в otsObjectBrowser.py и достаточно очевиден.
Перебор ключей - не очень эффективная процедура.
Если вы ограничитесь одним образцом (те k==keyList истинно только для одного элемента списка ключей как еслибы он был просто строкой) то возможна существенная оптимизация.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB