Part of my query looks something like this:
GRAPH g1: {VALUES (?ut) {$U1}
?IC_uri skos:related ?ut .
}
Normally, based on user input, $U1 gets a list of URIs. I would like to send for test purposes values for $U1 so that the declaration of values is ignored and all possible values are considered. In fact, it should produce the same results as:
GRAPH g1: {
# VALUES (?ut) {$U1}
?IC_uri skos:related ?ut .
}
I remember there was a way to do that, but I couldn't find it in the SPARQL specification.
I'd propose three options:
FILTER (?ut IN ($ut)), passing $ut instead of a list of URIs;
BIND ($ut as ?ut), passing $ut instead of a single URI;
VALUES (?ut) {(UNDEF)}, passing (UNDEF) instead of a space-separated list of (parentheses-enclosed) URIs.
Such SPARQL injections can not be considered safe.
The UNDEF keyword first mentioned in 10.2.2 VALUES Examples:
If a variable has no value for a particular solution in the VALUES clause, the keyword UNDEF is used instead of an RDF term.
Related
I have review multiple instructions on URL-parameters which all suggest 2 approaches:
Parameters can follow / forward slashes or be specified by parameter name and then by parameter value. so either:
1) http://numbersapi.com/42
or
2) http://numbersapi.com/random?min=10&max=20
For the 2nd one, I provide parameter name and then parameter value by using the ?. I also provide multiple parameters using ampersand.
Now I have see the request below which works fine but does not fit into the rules above:
http://numbersapi.com/42?json
I understand that the requests sets 42 as a parameter but why is the ? not followed by the parameter name and just by the value. Also the ? seems to be used as an ampersand???
From Wikipedia:
Every HTTP URL conforms to the syntax of a generic URI. The URI generic syntax consists of a hierarchical sequence of five components:
URI = scheme:[//authority]path[?query][#fragment]
where the authority component divides into three subcomponents:
authority = [userinfo#]host[:port]
This is represented in a syntax diagram as:
As you can see, the ? ends the path part of the URL and starts the query part.
The query part is usually a &-separated string of name=value pairs, but it doesn't have to be, so json is a valid value for the query part.
Or, as the Wikipedia articles says it:
An optional query component preceded by a question mark (?), containing a query string of non-hierarchical data. Its syntax is not well defined, but by convention is most often a sequence of attribute–value pairs separated by a delimiter.
It is also fairly common for request processors to treat a name=value pair that is missing the = sign, as if the it was name=.
E.g. if you're writing Servlet code and call servletRequest.getParameter("json"), it would return an empty string ("") for that last URL in the question.
I am currently trying to create pointers to datatype values as they cannot be linked directly. However, I would like to be able to evaluate the pointers from within the SPARQL environment, which raised specifically in the case that the desired value is part of an ordered rdf:List some questions for me. My approach is to use property paths within a SPARQL query in which I can use the defined individual, property and index of the ordered list that the pointer has attached to it.
Given the following example data with the shortened syntax for ordered lists by ttl:
ex:myObject ex:somePropery ("1" "2" "3") .
ex:myPointer ex:lookAtIndividual ex:myObject;
ex:lookAtProperty ex:someProperty ;
ex:lookAtIndex "3"^^xsd:integer .
Now I would like to create a SPARQL query that -- based on the pointer -- returns the value at the given index. To my understanding the query could/should look something like this:
SELECT ?value
WHERE {
ex:myPointer ex:lookAtIndividual ?individual ;
ex:lookAtProperty ?prop ;
ex:lookAtIndex ?index .
?individual ?prop/rdf:rest{?index-1}/rdf:first ?value .
}
But if I try to execute this query with TopBraid, it shows an error message that ?index has been found when <INTEGER> was expected. I also tried binding the index in the SPARQL query via BIND(?index-1 AS ?i), again without success. If the pointed value is not stored in a list, the query without property path works fine.
Is it in general possible to use a value that is connected via datatype property within a SPARQL query as path length for property paths?
This syntax: rdf:rest{<number>} is not standard SPARQL. So the short answer is, regrettably: no, you can't use variables as integers in SPARQL property paths, for the simple reason that you can't use integers in SPARQL property paths at all.
In an earlier draft of the SPARQL standard, there was a proposal to use this kind of syntax to allow specifying the min and max length of a property path, e.g. rdf:rest{1, 3} would match any paths using rdf:rest properties between length 1 and 3. But this was never fully standardized and most SPARQL engines don't implement it.
If you happen to use a SPARQL engine that does implement it, you will have to get in touch with the developers directly to ask if they can extend the mechanism to allow use of variables in this position (the error message suggests to me that it's currently just not possible).
As an aside: there's a SPARQL 1.2 community initiative going on. It only just got started but one of the proposals on the table is re-introducing this particular piece of functionality to the standard.
I got a TSV file that I'm converting with tarql.
Column prop has strings like dc:source, skos:broader etc. How can I convert these to the corresponding URLs? Assume I have all needed prefixes defined in the tarql query.
I can do this statically eg uri(concat(str(dc:),"source")) but how to do it dynamically? The problem can be narrowed to this: given a prefix dc: how to expand it to the appropriate URL?
Looked at ARQ functions but didn't find anything appropriate. If there's no other solution, I can use a VALUES table that repeats the prefixes and namespaces, but what an ugly solution...
The tarql:expandPrefixedName(?qname) function (completely coincidentally committed just today) does exactly what you need: It expands a prefixed name to a full IRI, using any prefixes declared in the query.
The tarql namespace is declared implicitly in every Tarql query.
I'm using the geonames dataset and there are two properties gn:officialName and gn:alternateName which both contain rdf:langString values. I hava a CONSTRUCT query where I would like to combine both values into one. Is that possible with SPARQL 1.1?
Bonus
How to prioritize the values of one property and only use the other on if there is no translation for a locale available?
You can combine them in the WHERE part of the CONSTRUCT query with a BIND( ... AS ?var) and use ?var in the CONSTRUCT template.
BIND ( CONCAT(?v1, ?v2) AS ?var)
If ?v1 and ?v2 are different languages, you need to take the str
BIND ( CONCAT(str(?v1), str(?v2)) AS ?var)
and maybe use strlang to set the language if you want.
I need to generate dynamically the name of a graph depending on the time.
I've tough that some think like
select ?g where {
bind(concat("<urn:myNewGraph_",str(now()),">") as ?g)
}
would have done the trick, but with Stardog I get a null result.
If instead I run this
select ?g where {
bind(concat("urn:myNewGraph_",str(now())) as ?g)
}
i get urn:myNewGraph_2015-05-28T09:37:11.823Z
Any Ideas?
moreover I'm not sure that even if i can get somehow a string like <urn:myNewGraph_2015-05-28T09:37:11.823Z> would have worked as a valid argument for a graph name as can be seen from this not-working test:
INSERT {graph ?g {<urn:s> <urn:p> <urn:o>}
where {
?g="<rn:myNewGraph_2015-05-28T09:37:11.823Z>"
}
is there a proper way to generate an urn/iri/uri dynamically?
Your original query looks correct, and produces a valid result when I execute it using a different SPARQL engine (Sesame), so I guess that you might want to report this to the Stardog developers as a possible bug.
However, to be able to use the value thus obtained it needs to be an actual URI (or IRI) - whereas what you're producing is a literal string.
You need to change two things: first of all, get rid of the enclosing < and > (these brackets are not actually part of the IRI) - so actually your second query is better. Second, use the IRI function to convert your string value to an IRI:
INSERT {GRAPH ?g {<urn:s> <urn:p> <urn:o>} }
WHERE {
BIND( IRI(CONCAT("urn:myNewGraph_",STR(NOW()))) as ?g)
}
Not sure it's necessary in your case, but in general you may need to use the ENCODE_FOR_URI function in there somewhere, to make sure that any special characters in your string are properly encoded/escaped before turning it into an IRI.