在文本SPARQL语法和SPIN RDF词汇表之间进行转换:如何添加rdfs:comment和sp:text

时间:2017-08-24 16:51:59

标签: java sparql jena topbraid-composer spin-rdf

使用SPIN API(http://topbraid.org/spin/api/)并使用https://github.com/spinrdf/spinrdf/blob/master/src-examples/org/topbraid/spin/examples/SPINParsingExample.java处的示例代码进行操作我试图将rdfs:comment和spin:text的处理添加到示例中。 Topbraid Composer免费版(TBC FE)确实允许每个SPIN规则发表一条评论,该评论包含在RDF中。 TBC FE还可以选择通过sp:text属性将SPIN SPARQL源代码包含为xsd:string值。我希望在示例的扩展版本中执行相同操作,然后将其转移到我希望嵌入SPIN规则编辑的工作代码中。

这是我当前扩展版的示例代码。请忽略日志警告。请注意,我在示例查询顶部插入的注释(第54行)会在输出中静默删除(输出也包括在下面)。

/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  See the NOTICE file distributed with this work for additional
 *  information regarding copyright ownership.
 */

package mil.disa.dso.spo.a2i.nsc.sharing2025.raaDemo;

import org.topbraid.spin.arq.ARQ2SPIN;
import org.topbraid.spin.arq.ARQFactory;
import org.topbraid.spin.model.Select;
import org.topbraid.spin.system.SPINModuleRegistry;

import org.apache.jena.query.Query;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.util.FileUtils;
import org.apache.jena.vocabulary.RDF;


/**
 * Converts between textual SPARQL representation and SPIN RDF model.
 * 
 * @author Holger Knublauch
 */
public class SPINParsingExample {

    /**
     * @param args
     */
    public static void main(String[] args) {

        // Register system functions (such as sp:gt (>))
        SPINModuleRegistry.get().init();

        // Create an empty OntModel importing SP
        Model model = ModelFactory.createDefaultModel();
        model.setNsPrefix("rdf", RDF.getURI());
        model.setNsPrefix("ex", "http://example.org/demo#");

        String query =
            "# This is an example SPARQL comment\n" +
            "SELECT ?person\n" +
            "WHERE {\n" +
            "    ?person a ex:Person .\n" +
            "    ?person ex:age ?age .\n" +
            "    FILTER (?age > 18) .\n" +
            "}";

        System.out.println("Original SPARQL query string:\n\n" + query);

        Query arqQuery = ARQFactory.get().createQuery(model, query);
        ARQ2SPIN arq2SPIN = new ARQ2SPIN(model);
        Select spinQuery = (Select) arq2SPIN.createQuery(arqQuery, null);

        // TODO what about the sp:text?  It's not in the artifacts printed below...
        // TODO figure out how to add a comment to the tokenized query... does not propagate from source string above
        //  perhaps this is through and addProperty call to add an rdfs:comment??  many calls, not clear how to use...
        //  get javadoc?

        System.out.println("\n-----");
        System.out.println("SPIN query in Turtle:\n");
        model.write(System.out, FileUtils.langTurtle);

        System.out.println("\n-----");
        System.out.println("SPIN query in XML:\n");
        model.write(System.out, FileUtils.langXML);

        System.out.println("\n-----");
        String str = spinQuery.toString();
        System.out.println("SPIN query:\n\n" + str);

        // Now turn it back into a Jena Query
        Query parsedBack = ARQFactory.get().createQuery(spinQuery);
        System.out.println("Jena query:\n" + parsedBack);
    }
}

以上输出......

log4j:WARN No appenders could be found for logger (Jena).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Original SPARQL query string:

# This is an example SPARQL comment
SELECT ?person
WHERE {
    ?person a ex:Person .
    ?person ex:age ?age .
    FILTER (?age > 18) .
}

-----
SPIN query in Turtle:

@prefix ex:    <http://example.org/demo#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sp:    <http://spinrdf.org/sp#> .

[ a                   sp:Select ;
  sp:resultVariables  ( [ sp:varName  "person" ]
                      ) ;
  sp:where            ( [ sp:object     ex:Person ;
                          sp:predicate  rdf:type ;
                          sp:subject    [ sp:varName  "person" ]
                        ]
                        [ sp:object     [ sp:varName  "age" ] ;
                          sp:predicate  ex:age ;
                          sp:subject    [ sp:varName  "person" ]
                        ]
                        [ a              sp:Filter ;
                          sp:expression  [ a        sp:gt ;
                                           sp:arg1  [ sp:varName  "age" ] ;
                                           sp:arg2  18
                                         ]
                        ]
                      )
] .

-----
SPIN query in XML:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:ex="http://example.org/demo#"
    xmlns:sp="http://spinrdf.org/sp#">
  <sp:Select>
    <sp:resultVariables rdf:parseType="Collection">
      <rdf:Description>
        <sp:varName>person</sp:varName>
      </rdf:Description>
    </sp:resultVariables>
    <sp:where rdf:parseType="Collection">
      <rdf:Description>
        <sp:object rdf:resource="http://example.org/demo#Person"/>
        <sp:predicate rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#type"/>
        <sp:subject rdf:parseType="Resource">
          <sp:varName>person</sp:varName>
        </sp:subject>
      </rdf:Description>
      <rdf:Description>
        <sp:object rdf:parseType="Resource">
          <sp:varName>age</sp:varName>
        </sp:object>
        <sp:predicate rdf:resource="http://example.org/demo#age"/>
        <sp:subject rdf:parseType="Resource">
          <sp:varName>person</sp:varName>
        </sp:subject>
      </rdf:Description>
      <sp:Filter>
        <sp:expression>
          <sp:gt>
            <sp:arg2 rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"
            >18</sp:arg2>
            <sp:arg1 rdf:parseType="Resource">
              <sp:varName>age</sp:varName>
            </sp:arg1>
          </sp:gt>
        </sp:expression>
      </sp:Filter>
    </sp:where>
  </sp:Select>
</rdf:RDF>

-----
SPIN query:

SELECT ?person
WHERE {
    ?person a ex:Person .
    ?person ex:age ?age .
    FILTER (?age > 18) .
}
Jena query:
SELECT  ?person
WHERE
  { ?person  a                     <http://example.org/demo#Person> ;
             <http://example.org/demo#age>  ?age
    FILTER ( ?age > 18 )
  }

我确定有一种方法可以将rdfs:comment和源代码(通过sp:text)添加到RDF,但我还没有找到它。我怀疑通过示例中的spinQuery实例化(第66行)调用Select类的方法可以做到这两点,但我不确定如何。任何指针将不胜感激。

这个问题与我先前回答的问题How to turn a SPARQL/SPIN query/rule into an RDF structure from Java?有关,但专注于RDF中的评论和源代码。

1 个答案:

答案 0 :(得分:1)

似乎您只能将rdfs:comment添加到查询的详细rdf格式中。 无法将rdfs:comment传递给sp:text,因为最后一个是字符串文字的谓词,您只能将其作为字符串的一部分。似乎Topbraid只允许通过RDF图进行注释,而文本查询仅存在于GUI中(作为分离模型)。建议:以RDF格式保存您的查询,在这种情况下,您也不会遇到前缀问题。

示例如何添加rdfs:commentsp:text

public static void main(String ... args) {
    Model model = ModelFactory.createDefaultModel();
    model.setNsPrefix("rdf", RDF.getURI());
    model.setNsPrefix("ex", "http://example.org/demo#");
    model.setNsPrefix("sp", SP.getURI());
    model.setNsPrefix("rdfs", RDFS.getURI());

    String query = "SELECT ?person\n" +
                    "WHERE {\n" +
                    "    ?person a ex:Person .\n" +
                    "    ?person ex:age ?age .\n" +
                    "    FILTER (?age > 18) .\n" +
                    "}";
    Query arqQuery = ARQFactory.get().createQuery(model, query);
    ARQ2SPIN arq2SPIN = new ARQ2SPIN(model);
    Select select1 = (Select) arq2SPIN.createQuery(arqQuery, null);
    select1.addProperty(RDFS.comment, "Comment1"); // <-- as part of rdf

    Resource anon = model.createResource();
    anon.addProperty(RDF.type, SP.Select);
    anon.addProperty(SP.text, model.createTypedLiteral(
            "# Comment2\n" + // <-- as part of string
            "SELECT ?person\n" +
            "WHERE {\n" +
            "    ?person a ex:Person .\n" +
            "    ?person ex:age ?age .\n" +
            "    FILTER (?age < 22) .\n" +
            "}"));
    Select select2 = anon.as(Select.class);
    System.out.println("========================");
    model.write(System.out, "ttl");
    System.out.println("========================");
    System.out.println("Select1:\n" + select1);
    System.out.println("Select2:\n" + select2);
}

输出:

========================
@prefix ex:    <http://example.org/demo#> .
@prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sp:    <http://spinrdf.org/sp#> .

_:b0    a              sp:Filter ;
        sp:expression  [ a        sp:gt ;
                         sp:arg1  [ sp:varName  "age" ] ;
                         sp:arg2  18
                       ] .

_:b1    sp:object     [ sp:varName  "age" ] ;
        sp:predicate  ex:age ;
        sp:subject    [ sp:varName  "person" ] .

[ a                   sp:Select ;
  rdfs:comment        "Comment1" ;
  sp:resultVariables  ( _:b2 ) ;
  sp:where            ( _:b3 _:b1 _:b0 )
] .

_:b3    sp:object     ex:Person ;
        sp:predicate  rdf:type ;
        sp:subject    [ sp:varName  "person" ] .

_:b2    sp:varName  "person" .

[ a        sp:Select ;
  sp:text  "# Comment2\nSELECT ?person\nWHERE {\n    ?person a ex:Person .\n    ?person ex:age ?age .\n    FILTER (?age < 22) .\n}"
] .
========================
Select1:
# Comment1
SELECT ?person
WHERE {
    ?person a ex:Person .
    ?person ex:age ?age .
    FILTER sp:gt(?age, 18) .
}
Select2:
# Comment2
SELECT ?person
WHERE {
    ?person a ex:Person .
    ?person ex:age ?age .
    FILTER (?age < 22) .
}