The approach I would take is to do this is multiple passes:
1/ remove from ElementPathBlock
2/ Look for elements that are now "empty"
e.g ElementFilter with empty
but also as there one arm of a UNION.
(2) is only one pass as the rewrite is done bottom up.
I would do this as a transformation rather than modifying the syntax
tree in place.
org.apache.jena.sparql.syntax.syntaxtransform
See also
ElementTransformCleanGroupsOfOne
which might be helpful to understand - its doing something different though.
It might be easier to work on the algebra, it's more regular. Then use
OpAsQuery to turn algebnra into a Query.
> I could not figure out how to remove the associated FILTER
> when visit(ElementFilter el) as below.
because you need to alter the ElementUnion which holds the ElementFilter.
{...} UNION {} will include a blank row for the {} on the right hand side.
Andy
On 28/01/16 13:14, Carlo.Allocca wrote:
Dear All,
I am using Jena for my project and I would like to submit the following
question: How to remove consistently a triple pattern given a SPARQL query?
EXAMPLE:
For example, considering the query “qString1” and the tp=“?boss ex:isBossOf
?ind .”
I need to remove tp from qString1, obtaining qString1. For “Consistently” I
mean that the clause FILTER gets affected (as it contains var that appears in
the triple pattern too), therefore it needs to be deleted too.
String qString1 =
" SELECT DISTINCT ?ind ?boss ?g where "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {?boss ex:isBossOf ?ind . Filter(?boss=\”rossi\”)} "
+ "}";
String qString2 =
" SELECT DISTINCT ?ind ?boss ?g “
+ “WHERE "
+ "{ "
+ " ?ind rdf:type ex:AssociatedResearcher ."
+ " {?ind rdf:type ?z. } UNION "
+ " {} "
+ "}";
The solution that I am trying to implement is based on a visitor
“SQRemoveTripleVisitor extends ElementVisitorBase”.
It is quite straightforward to remove the triple pattern when
visit(ElementPathBlock el)
@Override
public void visit(ElementPathBlock el) {
if (el == null) {
throw new
IllegalStateException("[SQRemoveTripleVisitor::visit(ElementPathBlock el)] The
ElementPathBlock is null!!");
}
ListIterator<TriplePath> it = el.getPattern().iterator();
while (it.hasNext()) {
final TriplePath tp1 = it.next();
if (this.tp != null) {
if (this.tp.matches(tp1.asTriple())) {
it.remove();
}
}
}
}
I could not figure out how to remove the associated FILTER when
visit(ElementFilter el) as below.
@Override
public void visit(ElementFilter el) {
//...get the variables of the FILTER expression
Expr filterExp = el.getExpr();//.getVarsMentioned().contains(el);
Set<Var> expVars = filterExp.getVarsMentioned();
//...get the variables of the triple pattern that we want to delete
Set<Var> tpVars = new HashSet();
Node subj = this.tp.getSubject();
if (subj.isVariable()) {
tpVars.add((Var) subj);
}
Node pred = this.tp.getPredicate();
if (pred.isVariable()) {
tpVars.add((Var) pred);
}
Node obj = this.tp.getObject();
if (obj.isVariable()) {
tpVars.add((Var) obj);
}
//...check whether the FILTER expression contains any of the triple
pattern’s variable
for(Var var:expVars){
//…if it does then we have to delete the entire FILTER expression
if(tpVars.contains(var)){
System.out.println("[SQRemoveTripleVisitor::visit(ElementFilter el)]
I NEED TO REMOVE THE FILTER!!!!!! ");
}
}
}
Please, may I ask for any help or idea on how to remove the filter?
Many Thanks in advance.
Best Regards,
Carlo
-- The Open University is incorporated by Royal Charter (RC 000391), an exempt
charity in England & Wales and a charity registered in Scotland (SC 038302).
The Open University is authorised and regulated by the Financial Conduct Authority.