java - 如何使用 ElementWalker 动态地将三元组添加到 Jena 查询?

标签 java sparql semantic-web jena

假设我有一些 jena 查询对象:

String query = "SELECT * WHERE{ ?s <some_uri> ?o ...etc. }";
Query q = QueryFactory.create(query, Syntax.syntaxARQ);

我想使用 ElementWalker 并将三元组添加到查询中,如下所示:

给定一个查询

SELECT * WHERE {
    ?s ?p ?o;
       ?p2 ?o2.
    ?s2 ?p3 ?o3.
}

我希望添加一个三重 s.t.查询类似于:

    SELECT * WHERE {
    ?s ?p ?o;
       ?p2 ?o2.
 -->?s <some_url> "value". //added
    ?s2 ?p3 ?o3.
}

我知道有一些方法可以添加到顶层 ( Jena Tutorial ),但我想在使用 ElementWalker 遍历三元组时以某种方式添加它们:

ElementWalker.walk(query.getQueryPattern(), new ElementVisitorBase(){

        public void visit(ElementPathBlock el) {

            // when it's a block of triples, add in some triple
            ElementPathBlock elCopy = new ElementPathBlock();
            Iterator<TriplePath> triples = el.patternElts();
            int index = 0;
            int numAdded = 0;
            while (triples.hasNext()) {
                TriplePath t = triples.next();
                if(t.getSubject().equals(/*something*/)){
                    //add triple here, something like:
                    elCopy.addTriple(index+numAdded, /*someTriple*/);
                    numAdded++;
                }
                index++;
            }
            el = elCopy;
        }

        public void visit(ElementSubQuery el) {

            // get the subquery and walk it
            ElementGroup subQP = (ElementGroup) el.getQuery().getQueryPattern();
            ElementWalker.walk(subQP, this);
        }

        public void visit(ElementOptional el) {

            // get optional elements and walk them
            Element optionalQP = el.getOptionalElement();
            ElementWalker.walk(optionalQP, this);
        }
    });

上面代码的问题在于它成功地将三元组添加到 ElementPathBlock (el),但更改不会延续到查询本身。我希望在访问查询内部的这个特定 ElementPathBlock 时成功修改查询。

感谢任何帮助。

最佳答案

此代码使用 walker 在主题为 ?d 的任何三元组之后添加 ?d ?d ?d。由于主题 ?d 的查询中有多个三元组,因此会插入多个 ?d ?d ?d 实例,并保留更改。

import java.util.ListIterator;

import com.hp.hpl.jena.graph.Triple;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.sparql.core.TriplePath;
import com.hp.hpl.jena.sparql.core.Var;
import com.hp.hpl.jena.sparql.syntax.ElementPathBlock;
import com.hp.hpl.jena.sparql.syntax.ElementVisitorBase;
import com.hp.hpl.jena.sparql.syntax.ElementWalker;

public class ElementWalkerExample {
    public static void main(String[] args) {
        final String queryString  = "" +
            "SELECT * WHERE {\n" +
            " ?a ?b ?c1 ;\n" +
            "    ?b ?c2 .\n" +
            " ?d ?e ?f .\n" +
            " ?g ?h ?i .\n" +
            "{ ?p ?q ?r .\n" +
            "  ?d ?e2 ?f2 . }\n" +
            "}";
        final Query query = QueryFactory.create( queryString );
        System.out.println( "== before ==\n"+query );
        ElementWalker.walk( query.getQueryPattern(), 
                new ElementVisitorBase() {
                    @Override
                    public void visit(ElementPathBlock el) {
                        ListIterator<TriplePath> it = el.getPattern().iterator();
                        while ( it.hasNext() ) {
                            final TriplePath tp = it.next();
                            final Var d = Var.alloc( "d" );
                            if ( tp.getSubject().equals( d )) {
                                it.add( new TriplePath( new Triple( d, d, d )));
                            }
                        }
                    }
        });
        System.out.println( "== after ==\n"+query );
    }
}

输出是:

== before ==
SELECT  *
WHERE
  { ?a ?b ?c1 .
    ?a ?b ?c2 .
    ?d ?e ?f .
    ?g ?h ?i
    { ?p ?q ?r .
      ?d ?e2 ?f2
    }
  }

== after ==
SELECT  *
WHERE
  { ?a ?b ?c1 .
    ?a ?b ?c2 .
    ?d ?e ?f .
    ?d ?d ?d .
    ?g ?h ?i
    { ?p ?q ?r .
      ?d ?e2 ?f2 .
      ?d ?d ?d
    }
  }

关于java - 如何使用 ElementWalker 动态地将三元组添加到 Jena 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17840744/

相关文章:

java - 如何以编程方式将标题栏颜色更改为十六进制值?

sparql - 带有性别词尾变化的 RDF 语言标签

java - 在语义 Web 应用程序中将 URI 作为请求参数处理

java - 如何将自定义消息附加到异常(在不能抛出异常的重写方法中)?

java - 每次调用 ActionListener 时,如何明显地更改 JScrollPane 的内容?

java - 如何在我的 Mapbox 图层的左上角添加导航菜单和抽屉

sparql - 维基数据查询服务,过滤高于/低于某个值的值/字符串

sparql - 插入有序列表本体中的位置

rdf - 将多个文件增量数据加载到耶拿

sparql - 为什么过滤器在这种情况下不起作用?