I'm pretty new with SPARQL and I'm trying to insert some kind of language filter for literals returned by my query template. The problem is the dataset doesn't provide a well structured tagging system so I got to restrict results in some conditional way AND make these conditions work with the following template:
SELECT distinct ?s ?p ?o WHERE {
?this :is :something. // this pattern is passed as argument
// to the js func that manage the
// query
{
bind(?this as ?s)
?s ?p ?o.
// here i putted my filters
}
}
The filter I want to add should provide a way to return only the "english version" for patterns with literals. if no english version is provided then return the untagged one - there is always an untagged one.
Based on solutions for similar questions, I tried with this:
filter(!isLiteral(?o) || (langMatches(lang(?o), 'en')) || lang(?o)='')
but - of course - ends up returning both: english and untagged literals.
Another way, that solved the problem for someone, is using two OPTIONAL
pattern like here:
optional {
?country rdfs:label ?label
filter langMatches(lang(?label), "en")
}
optional {
?country rdfs:label ?label
}
but I have the ?s ?p ?o
pattern in my template that already returns all the triples associated with a specific subject, then optional patterns seems useless here.
I've read other questions similar to these but no one seems to fits my query template, so if someone can help me understanding this I'll be grateful.
If I'm interpretting your question right, it is doable using a single FILTER
with several disjuncts ordered in manner of preference, e.g. like:
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
select * where {
bind(skos:member as ?s)
?s ?p ?o .
filter (
!isLiteral(?o) ||
langmatches(lang(?o), "en")
|| (langmatches(lang(?o), "") && not exists {
?s ?p ?other.
filter(isLiteral(?other) && langmatches(lang(?other), "en"))
}))
}
?o
@en
@en
tagHTH
the use of skos:member
in the query above is just to have something bound to the ?s
and it is arbitraty ...