From fea72715438bf7e340fb08a22fbb97df31dd2ec8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 22 Jan 2015 15:31:36 +0100 Subject: [PATCH] Result construction MPSPARCL-4 Configuration item "field" replaced by "form", which allows SELECT/CONSTRUCT to be defined. The triple store is now returning application/rdf+xml response and this is what's decoded. --- bibframe/triplestore.xml | 20 +++++++++++-- doc/sparql.xml | 7 ++--- src/filter_sparql.cpp | 74 ++++++++++++++++++++++++++++++++++++---------- src/sparql.c | 5 ++-- 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/bibframe/triplestore.xml b/bibframe/triplestore.xml index 7a6f506..56b80fa 100644 --- a/bibframe/triplestore.xml +++ b/bibframe/triplestore.xml @@ -3,7 +3,23 @@ rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns bf: http://bibframe.org/vocab/ - DISTINCT ?work ?wtitle ?creatorlabel ?subjectlabel +
SELECT DISTINCT ?work ?wtitle ?creatorlabel ?subjectlabel
+ ?work a bf:Work + + ?work bf:workTitle ?wt + ?wt bf:titleValue ?wtitle + ?wt bf:titleValue %v FILTER(contains(%v, %s)) + ?work bf:creator ?creator + ?creator bf:label ?creatorlabel + ?creator bf:label %v FILTER(contains(%v, %s)) + ?work bf:subject ?subject + ?subject bf:label ?subjectlabel + ?subject bf:label %v FILTER(contains(%v, %s)) +
+ + rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns + bf: http://bibframe.org/vocab/ +
CONSTRUCT { ?work bf:title ?title . ?work bf:author ?creator . ?work bf:instanceTitle ?it }
?work a bf:Work ?work bf:workTitle ?wt @@ -19,7 +35,7 @@ rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns bf: http://bibframe.org/vocab/ - DISTINCT ?instance ?title ?format +
SELECT DISTINCT ?instance ?title ?format
?instance a bf:Instance ?instance bf:title ?title diff --git a/doc/sparql.xml b/doc/sparql.xml index 838dce1..d374ef6 100644 --- a/doc/sparql.xml +++ b/doc/sparql.xml @@ -41,12 +41,11 @@ - <field/> + <form/> - Optional section for controlling what data rows are selected in the - SPARQL statement and how they are mapped to the output document, all - variables (\*) are selected when none is provided. + SPARQL Query formulation selection. SHould start with one of the + query forms: SELECT or CONSTRUCT. diff --git a/src/filter_sparql.cpp b/src/filter_sparql.cpp index 6bc889e..8aa9bab 100644 --- a/src/filter_sparql.cpp +++ b/src/filter_sparql.cpp @@ -269,26 +269,67 @@ static xmlNode *get_result(xmlDoc *doc, Odr_int *sz, Odr_int pos) { xmlNode *ptr = xmlDocGetRootElement(doc); Odr_int cur = 0; - for (; ptr; ptr = ptr->next) - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "sparql")) - break; - if (ptr) + + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "RDF")) { - for (ptr = ptr->children; ptr; ptr = ptr->next) - if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "results")) - break; + ptr = ptr->children; + + while (ptr && ptr->type != XML_ELEMENT_NODE) + ptr = ptr->next; + if (ptr && ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "Description")) + { + xmlNode *p = ptr->children; + + while (p && p->type != XML_ELEMENT_NODE) + p = p->next; + if (p && p->type == XML_ELEMENT_NODE && + !strcmp((const char *) p->name, "type")) + { /* SELECT RESULT */ + for (ptr = ptr->children; ptr; ptr = ptr->next) + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "solution")) + { + if (cur++ == pos) + break; + } + } + else + { /* CONSTRUCT result */ + for (; ptr; ptr = ptr->next) + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "Description")) + { + if (cur++ == pos) + break; + } + } + } } - if (ptr) + else { - for (ptr = ptr->children; ptr; ptr = ptr->next) + for (; ptr; ptr = ptr->next) if (ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "result")) - { - if (cur++ == pos) + !strcmp((const char *) ptr->name, "sparql")) + break; + if (ptr) + { + for (ptr = ptr->children; ptr; ptr = ptr->next) + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "results")) break; - } + } + if (ptr) + { + for (ptr = ptr->children; ptr; ptr = ptr->next) + if (ptr->type == XML_ELEMENT_NODE && + !strcmp((const char *) ptr->name, "result")) + { + if (cur++ == pos) + break; + } + } } if (sz) *sz = cur; @@ -321,7 +362,6 @@ Z_Records *yf::SPARQL::Session::fetch( if (!node) break; assert(node->type == XML_ELEMENT_NODE); - assert(!strcmp((const char *) node->name, "result")); xmlNode *tmp = xmlCopyNode(node, 1); xmlBufferPtr buf = xmlBufferCreate(); xmlNodeDump(buf, tmp->doc, tmp, 0, 0); @@ -353,6 +393,8 @@ Z_APDU *yf::SPARQL::Session::run_sparql(mp::Package &package, z_HTTP_header_add(odr, &gdu->u.HTTP_Request->headers, "Content-Type", "application/x-www-form-urlencoded"); + z_HTTP_header_add(odr, &gdu->u.HTTP_Request->headers, + "Accept", "application/rdf+xml"); const char *names[2]; names[0] = "query"; names[1] = 0; diff --git a/src/sparql.c b/src/sparql.c index e551ead..fbd8c91 100644 --- a/src/sparql.c +++ b/src/sparql.c @@ -322,7 +322,7 @@ int yaz_sparql_from_rpn_stream(yaz_sparql_t s, { ; } - else if (!strncmp(e->pattern, "field", 5)) + else if (!strcmp(e->pattern, "form")) { ; } @@ -332,10 +332,9 @@ int yaz_sparql_from_rpn_stream(yaz_sparql_t s, } } pr("\n", client_data); - pr("SELECT", client_data); for (e = s->conf; e; e = e->next) { - if (!strncmp(e->pattern, "field", 5)) + if (!strcmp(e->pattern, "form")) { pr(" ", client_data); pr(e->value, client_data); -- 1.7.10.4