Rdflib, Python: Существуют ли какие-либо методы обрамления объектов для получения вложенной структуры dict/list из графа а-ля JSON-LD?

Запрос Rdflib CONSTRUCT возвращает список кортежей, представляющих граф. Однако языки шаблонов обычно наиболее удобны с древовидными структурами вложенных смешанных слов и списков (поскольку структура хорошо согласуется с древовидной структурой разметки HTML). На самом деле, SELECT не лучше в этом отношении, но денормализованный вариант тех же данных.

Довольно легко придумать какое-то специальное преобразование, но, может быть, есть какой-то идиоматический способ с учетом графика и несколько подсказок для "опорных точек", который создает дерево?

Например, если у нас есть график, содержащий индивидуумы Query и ResultVar (со свойствами данных, такими как метки и т. Д.), То дерево может быть списком Query с дочерними элементами ResultVar:

[
{'name': 'q1', 'uri': '...', 'children': 
  [{'name': 'x', 'value': '1', ... },
   {'name': 'y', 'value': '1', ... },
   ...
  ]},
...
]

Для этого мы можем намекнуть на метод использования порядка Query - ResultVar. И результат прост в использовании с вложенными "циклами", которые генерируют HTML-разметку в шаблоне.

Мне бы не хотелось изобретать велосипед, и я думаю, что проблема такого рода не уникальна, но я не нашел никакого решения.

Тем не менее, я не хочу подход ORM, так как это означает наличие схемы в коде, и я не хочу, чтобы это было реализовано.

РЕДАКТИРОВАТЬ: Чтобы прояснить возможные недоразумения, Query / ResultVar является лишь примером. Вместо этого я мог бы использовать Блог / Комментарий или Календарь / Событие.

EDIT2 Похоже, что то, что ищется здесь, является кадрирование объекта, как используется в JSON-LD:

Обрамление - это процесс получения документа JSON-LD, который выражает граф информации, и применения определенного макета графа (называемого фреймом).

JSON-LD Framing позволяет разработчикам запрашивать на примере и принудительно задавать конкретную компоновку дерева в документ JSON-LD.

Итак, что здесь нужно, так это способ создания фреймов в rdflib, Python. В этом документе ("JSON-LD: разбивка циклов и кадрирование объектов") дается популярное объяснение того, что ищет мой вопрос, но есть ли что-то подобное для Python?

2 ответа

Решение

"Обрамление объекта", которое позволяет преобразовывать документ в RDF-модели через JSON-LD в древовидную форму, более подходящее для некоторых сценариев применения, обеспечивается библиотекой pyld:

https://github.com/digitalbazaar/pyld

Граф результатов может быть сериализован в JSON-LD с учетом так называемого контекста (терминология JSON-LD), а затем с учетом фрейма (еще один термин JSON-LD, описанный в проекте):

jsonld.frame(doc, frame)

создаст "структурированную" структуру данных, фактически дерево с фиксированной разметкой, которое может использоваться приложением.

Для более конкретных случаев, таких как древовидные сценарии создания графического интерфейса пользователя, словарь Френеля должен быть "способом RDF". Однако, как отобразить данные RDF, описанные лексикой Френеля? предполагает, что LDP (платформа связанных данных) является более продвинутым подходом.

То, что вы просите, может быть реализовано с SPARQLWrapper2 учебный класс. К сожалению, документы для этого немного "сложны" для понимания, если не сказать больше. Но в общих документах есть хороший пример:

from SPARQL import SPARQLWrapper2
queryString = "SELECT ?subj ?o ?opt WHERE { ?subj <http://a.b.c> ?o. OPTIONAL { ?subj <http://d.e.f> ?opt }}"
sparql = SPARQLWrapper2("http://localhost:2020/sparql")
# add a default graph, though that can also be in the query string
sparql.addDefaultGraph("http://www.example.com/data.rdf")
sparql.setQuery(queryString)
try :
    ret = sparql.query()
    print ret.variables  # this is an array consisting of "subj", "o", "opt"
        if (u"subj",u"prop",u"opt") in ret :
               # there is at least one binding covering the optional "opt", too
               bindings = ret[u"subj",u"o",u"opt"]
               # bindings is an array of dictionaries with the full bindings
               for b in bindings :
                       subj = b[u"subj"].value
                       o    = b[u"o"].value
                       opt  = b[u"opt"].value
                       # do something nice with subj, o, and opt
        # another way of accessing to values for a single variable:
        # take all the bindings of the "subj"
        subjbind = ret.getValues(u"subj") # an array of Value instances
        ...
except:
    deal_with_the_exception()

Так что адаптированный к вашему случаю вы можете использовать children = ret.getValues(u'q1'),

Другие вопросы по тегам