Jena语义Web开发101
2015/05/28更新 代码在 https://github.com/zhoujiagen/semanticWebTutorialUsingJena
前言
该手册参考和扩展“Hebeler J, Fisher M, et al.Web 3.0与Semantic Web编程[M]. 清华大学出版社, 北京.2010.”中的HelloWorld。
在描述中,不将Web本体与描述逻辑的术语做区分,尽量采用Web本体的英文表述,下面列出Web本体与描述逻辑的术语对应关系:
Web本体 | 描述逻辑 |
Class | Concept |
Property Object Property Data Property |
Role |
Individual | Instance |
计划记录类容:
1 Jena RDF API使用
2 用SPARQL做RDF navigate
3 手动本体对准(ontology alignment)
4 Jena OWL推理(Inference)
5 Jena Rule推理
内容
0 数据!数据!数据!
数据准备思路:将TBox与ABox分开,两个本体(TBox1, ABox1, TBox2, ABox2),其中ABox1与TBox1的命名空间不同,ABox2与TBox2的命名空间相同。
TBox1:FOAF的规范(http://xmlns.com/foaf/spec/)
ABox1:生成自FOAF数据的链接(http://www.ldodds.com/foaf/foaf-a-matic)
TBox2, ABox2: 如何用Protege建立本体(http://protegewiki.stanford.edu/wiki/Ontology101, http://130.88.198.11/tutorials/protegeowltutorial/),话外Protege官网现在变得好炫.
1 Jena RDF API使用
这里只涉及如何用RDF文件填充Model,code sketch如下:
Model model = ModelFactory.createDefaultModel(); InputStream is = FileManager.get().open("E:/码农的世界/码农的自我修养/semantic web/workspace/foafData.rdf"); model.read(is, "http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl"); is.close();
2 用SPARQL做RDF navigate
SPARQL的全称是SPARQL Protocol and RDF Query Language,既是一个定义如何执行RDF查询、更新操作的协议,也是一个RDF查询语言。
Jena中的Graph抽象比较好,这是个类似于关系型数据库中视图的概念,只是Graph中基础的数据结构是形如<Subject, Predicate, Object>的Triple,SPARQL作为查询语言,就是在Graph中Triple中定位和导航数据。
Jena ARQ API的code sketch如下:
//组装查询字符串StringBuilder sb = new StringBuilder(); sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>").append(NEWLINE).append("PREFIX owl: <http://www.w3.org/2002/07/owl#>") .append(NEWLINE).append("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>").append(NEWLINE) .append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>").append(NEWLINE).append("PREFIX foaf: <http://xmlns.com/foaf/0.1/>") .append(NEWLINE).append("PREFIX myfoaf: <http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#>").append(NEWLINE) .append("PREFIX people: <http://www.people.com#>").append(NEWLINE); sb.append("SELECT DISTINCT ?name").append(NEWLINE).append("WHERE { myfoaf:me foaf:name ?name}").append(NEWLINE); //执行查询 sparql(model, sb.toString(), "?name"); private static void sparql(Model model, String query, String field) { Query q = QueryFactory.create(query); QueryExecution qexec = QueryExecutionFactory.create(q, model); System.out.println("Plan to run SPARQL query: "); System.out.println(BOUNDARY); System.out.println(query); System.out.println(BOUNDARY); ResultSet rs = qexec.execSelect(); while (rs.hasNext()) { QuerySolution qs = rs.nextSolution(); RDFNode name = qs.get(field);// 暂用RDFNode if (name != null) { System.out.println("Hello to " + name); } else { System.out.println("No friends found!"); } } qexec.close(); }
3 手动本体对准(ontology alignment)
这个例子涉及4个对准:
两个命名空间中的Class等价、两个命名空间中Property等价、两个命名空间中Property蕴涵和两个命名空间中Individual等价(异名同义)。
下图中红色箭头表示本体对准关系,没有展示Property之间的对准关系(该图用Graphviz手工生成,自动生成在下一步的计划中):
本体对准code sketch如下,其中Model shema仅加载两个本体的TBox:
// [1]people:Individual = foaf:Person Resource resource = schema.createResource(PEOPLE_NS + "#Individual"); Property property = schema.createProperty(OWL_URL + "equivalentClass"); Resource object = schema.createResource(FOAF_URL + "Person"); schema.add(resource, property, object); // [2]people:hasName = foaf:name resource = schema.createResource(PEOPLE_NS + "#hasName"); property = schema.createProperty(OWL_URL + "equivalentProperty"); object = schema.createResource(FOAF_URL + "name"); schema.add(resource, property, object); // [3]people:hasFriend < foaf:knows resource = schema.createResource(PEOPLE_NS + "#hasFriend"); property = schema.createProperty(RDFS_URL + "subPropertyOf"); object = schema.createResource(FOAF_URL + "knows"); schema.add(resource, property, object); // [4]myfoaf:me = people:individual_5 resource = schema.createResource(MYFOAF_NS + "#me"); property = schema.createProperty(OWL_URL + "sameAs"); object = schema.createResource(PEOPLE_NS + "#individual_5"); schema.add(resource, property, object);
4 Jena OWL推理(Inference)
下表是OWL支持的推理形式的概要:
OWL构造/描述逻辑支持的推理
语义构造 |
推理规则 |
概念包含 |
C ⊑ D ∧ C(a) ⇒ D(a) |
概念互斥 |
C ⊓ D ⊑ ⊥ ∧ C(a) ∧ D(b) ⇒ a≉ b |
关系包含 |
R ⊑ S ∧ R(a, b) ⇒ S(a, b) |
关系定义域 |
domain(R, C) ∧ R(a, b) ⇒ C(a) |
关系值域 |
range(R, C) ∧ R(a, b) ⇒ C(b) |
自反关系 |
R ⊑ id(C) ⇒ R(a, a) |
传递关系 |
R+(a, b) ∧ R+(b, c) ⇒ R+(a, c) |
对称关系 |
R ≡ R⁻∧ R(a, b) ⇒ R(b, a) |
关系组合 |
R ∘ S ⊑ R ′∧ R(a, b) ∧ S(b, c) ⇒ R′(a, c) |
互逆关系 |
R(a, b) ⇒ R⁻(a, b) R⁻(a, b) ⇒ R(a, b) |
函数关系 |
Rf(a, b) ∧ Rf(a, c) ⇒ b≈ c |
键 |
HasKey(C, R)∧ C(a) ∧ C(b) ∧ R(a, c) ∧ R(b, c) ⇒ b≈ c |
Jena API关于OWL推理的基本策略是用Reasoner绑定TBox,在代表ABox的Model对象基础上创建出推理后模型IntModel对象。
code sketch如下:
InfModel inferredModel = null; Reasoner reasoner = ReasonerRegistry.getOWLReasoner(); reasoner = reasoner.bindSchema(schema);// tbox inferredModel = ModelFactory.createInfModel(reasoner, friendsModel);// abox
5 Jena Rule推理
尽管语义Web事实上的规则语言标准是SWRL,但Jena提供了自己的规则语言,一些值得关注的特性是Jena规则支持前向推理和后向推理、可以动态生成匿名节点。
使用Jena Rule执行推理的code sketch如下:
String rule = "[gmailFriend: (?person <http://xmlns.com/foaf/0.1/mbox_sha1sum> ?email), strConcat(?email, ?lit), regex(?lit, '(.*gmail.com)')" + "-> (?person " + RDF_TYPE + " <http://www.people.com#GmailPerson>)]"; Reasoner ruleReasoner = new GenericRuleReasoner(Rule.parseRules(rule)); ruleReasoner = ruleReasoner.bindSchema(schema); inferredModel = ModelFactory.createInfModel(ruleReasoner, friendsModel);
6 总结
本手册记录了Jena如何加载RDF文件填充Model、如何用SPARQL导航Model、如何执行OWL和Jena Rule推理,也简单介绍了本体对准。
数据
foafSchema.rdf (NS=http://xmlns.com/foaf/0.1/)
下载链接为http://xmlns.com/foaf/spec/index.rdf,将其重名为foafSchema.rdf。
foafData.rdf (NS=http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl)
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY foaf "http://xmlns.com/foaf/0.1/" > <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" > <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" > <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" > ]> <rdf:RDF xmlns="http://www.w3.org/2002/07/owl#" xml:base="http://www.w3.org/2002/07/owl" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <Ontology rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl"> <imports rdf:resource="http://xmlns.com/foaf/0.1/"/> </Ontology> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Annotation properties // /////////////////////////////////////////////////////////////////////////////////////// --> <AnnotationProperty rdf:about="&foaf;givenname"/> <AnnotationProperty rdf:about="&foaf;mbox_sha1sum"/> <AnnotationProperty rdf:about="&foaf;nick"/> <AnnotationProperty rdf:about="&foaf;homepage"/> <AnnotationProperty rdf:about="&foaf;depiction"/> <AnnotationProperty rdf:about="&foaf;title"/> <AnnotationProperty rdf:about="&foaf;workInfoHomepage"/> <AnnotationProperty rdf:about="&foaf;workplaceHomepage"/> <AnnotationProperty rdf:about="&foaf;family_name"/> <AnnotationProperty rdf:about="&foaf;knows"/> <AnnotationProperty rdf:about="&foaf;schoolHomepage"/> <AnnotationProperty rdf:about="&foaf;phone"/> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Datatypes // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Individuals // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Ontology --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Ontology"> <rdf:type rdf:resource="http://schema.org/Person"/> <foaf:name rdf:datatype="&xsd;string">I. M. Ontology</foaf:name> <rdfs:seeAlso rdf:datatype="&xsd;string">http://ont.com</rdfs:seeAlso> <foaf:mbox_sha1sum rdf:datatype="&xsd;string">mailto:ont@gmail.com</foaf:mbox_sha1sum> </NamedIndividual> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Reasoner --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Reasoner"> <rdf:type rdf:resource="http://schema.org/Person"/> <foaf:name rdf:datatype="&xsd;string">Ican Reason</foaf:name> <rdfs:seeAlso rdf:datatype="&xsd;string">http://reasoner.com</rdfs:seeAlso> <foaf:mbox_sha1sum rdf:datatype="&xsd;string">maillto:reason@hotmail.com</foaf:mbox_sha1sum> </NamedIndividual> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Statement --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Statement"> <rdf:type rdf:resource="http://schema.org/Person"/> <foaf:name rdf:datatype="&xsd;string">Makea Statement</foaf:name> <rdfs:seeAlso rdf:datatype="&xsd;string">http://statement.com</rdfs:seeAlso> <foaf:mbox_sha1sum rdf:datatype="&xsd;string">mailto:mstatement@gmail.com</foaf:mbox_sha1sum> </NamedIndividual> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://blog.sina.com.cn/zhoujiagenontology --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://blog.sina.com.cn/zhoujiagenontology"/> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://s8.sinaimg.cn/mw690/002RJaAlty6FSYutTO777&690 --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://s8.sinaimg.cn/mw690/002RJaAlty6FSYutTO777&690"> <rdf:type rdf:resource="&foaf;Image"/> </NamedIndividual> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.cqu.edu.cn/ --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.cqu.edu.cn/"/> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.founderinternational.com/ --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.founderinternational.com/"/> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#me --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#me"> <rdf:type rdf:resource="http://schema.org/Person"/> <foaf:givenname rdf:datatype="&xsd;string">Semantic</foaf:givenname> <foaf:name rdf:datatype="&xsd;string">Semantic Web</foaf:name> <foaf:family_name rdf:datatype="&xsd;string">Web</foaf:family_name> <foaf:nick rdf:datatype="&xsd;string">Webby</foaf:nick> <foaf:title rdf:datatype="&xsd;string">master</foaf:title> <foaf:mbox_sha1sum rdf:datatype="&xsd;string">zhoujiagen@gmail.com</foaf:mbox_sha1sum> <foaf:knows rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Ontology"/> <foaf:knows rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Reasoner"/> <foaf:knows rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#Statement"/> <foaf:homepage rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://blog.sina.com.cn/zhoujiagenontology"/> <foaf:depiction rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://s8.sinaimg.cn/mw690/002RJaAlty6FSYutTO777&690"/> <foaf:schoolHomepage rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.cqu.edu.cn/"/> <foaf:workplaceHomepage rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.founderinternational.com/"/> <foaf:workInfoHomepage rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#http://www.founderinternational.com/"/> <foaf:phone rdf:resource="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#tel:13552854032"/> </NamedIndividual> <!-- http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#tel:13552854032 --> <NamedIndividual rdf:about="http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#tel:13552854032"/> </rdf:RDF> <!-- Generated by the OWL API (version 3.2.5.1912) http://owlapi.sourceforge.net -->
peopleSchema.rdf (NS=http://www.people.com)
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY owl "http://www.w3.org/2002/07/owl#" > <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" > <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" > <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" > ]> <rdf:RDF xmlns="http://www.people.com#" xml:base="http://www.people.com" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <owl:Ontology rdf:about="http://www.people.com"/> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Datatypes // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Object Properties // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#hasFriend --> <owl:ObjectProperty rdf:about="http://www.people.com#hasFriend"> <rdfs:range rdf:resource="http://www.people.com#Individual"/> <rdfs:domain rdf:resource="http://www.people.com#Individual"/> </owl:ObjectProperty> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Data properties // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#hasName --> <owl:DatatypeProperty rdf:about="http://www.people.com#hasName"> <rdfs:domain rdf:resource="http://www.people.com#Individual"/> <rdfs:range rdf:resource="&xsd;string"/> </owl:DatatypeProperty> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Classes // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#GmailPerson --> <owl:Class rdf:about="http://www.people.com#GmailPerson"> <rdfs:subClassOf rdf:resource="http://www.people.com#Individual"/> </owl:Class> <!-- http://www.people.com#Individual --> <owl:Class rdf:about="http://www.people.com#Individual"/> </rdf:RDF> <!-- Generated by the OWL API (version 3.2.5.1912) http://owlapi.sourceforge.net -->
peopleData.rdf (NS=http://www.people.com)
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY www "http://www.people.com#" > <!ENTITY owl "http://www.w3.org/2002/07/owl#" > <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" > <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" > <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" > ]> <rdf:RDF xmlns="http://www.people.com#" xml:base="http://www.people.com" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:www="http://www.people.com#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <owl:Ontology rdf:about="http://www.people.com"/> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Datatypes // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Object Properties // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#hasFriend --> <owl:ObjectProperty rdf:about="&www;hasFriend"> <rdfs:range rdf:resource="&www;Individual"/> <rdfs:domain rdf:resource="&www;Individual"/> </owl:ObjectProperty> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Data properties // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#hasName --> <owl:DatatypeProperty rdf:about="&www;hasName"> <rdfs:domain rdf:resource="&www;Individual"/> <rdfs:range rdf:resource="&xsd;string"/> </owl:DatatypeProperty> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Classes // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#GmailPerson --> <owl:Class rdf:about="&www;GmailPerson"> <rdfs:subClassOf rdf:resource="&www;Individual"/> </owl:Class> <!-- http://www.people.com#Individual --> <owl:Class rdf:about="&www;Individual"/> <!-- /////////////////////////////////////////////////////////////////////////////////////// // // Individuals // /////////////////////////////////////////////////////////////////////////////////////// --> <!-- http://www.people.com#individual_5 --> <owl:NamedIndividual rdf:about="&www;individual_5"> <rdf:type rdf:resource="&www;Individual"/> <hasName rdf:datatype="&xsd;string">Sem Web</hasName> <hasFriend rdf:resource="&www;individual_6"/> <hasFriend rdf:resource="&www;individual_7"/> </owl:NamedIndividual> <!-- http://www.people.com#individual_6 --> <owl:NamedIndividual rdf:about="&www;individual_6"> <rdf:type rdf:resource="&www;Individual"/> <hasName rdf:datatype="&xsd;string">Web O Data</hasName> </owl:NamedIndividual> <!-- http://www.people.com#individual_7 --> <owl:NamedIndividual rdf:about="&www;individual_7"> <rdf:type rdf:resource="&www;Individual"/> <hasName rdf:datatype="&xsd;string">Mr. OWL</hasName> </owl:NamedIndividual> </rdf:RDF> <!-- Generated by the OWL API (version 3.2.5.1912) http://owlapi.sourceforge.net -->
代码
代码1 常量类
package util; /** * <ul> * <li>Author: zhoujg | Date: 2014-3-23 下午1:25:14</li> * <li>Description: 常量类</li> * </ul> */ public class Constants { public static final String NEWLINE = System.getProperty("line.separator"); public static final String TAB = System.getProperty("\t"); public static final String BOUNDARY = "-----------------------------------------------------------------------"; public static final String RDF_URL = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; public static final String RDFS_URL = "http://www.w3.org/2000/01/rdf-schema#"; public static final String OWL_URL = "http://www.w3.org/2002/07/owl#"; public static final String XSD_URL = "http://www.w3.org/2001/XMLSchema#"; public static final String FOAF_URL = "http://xmlns.com/foaf/0.1/"; public static final String RDF_TYPE = "<" + RDF_URL + "type>"; }
代码2 HelloSemanticWeb
package helloworld; import java.io.IOException; import java.io.InputStream; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.rdf.model.InfModel; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.reasoner.Reasoner; import com.hp.hpl.jena.reasoner.ReasonerRegistry; import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner; import com.hp.hpl.jena.reasoner.rulesys.Rule; import com.hp.hpl.jena.util.FileManager; import static util.Constants.*; /** * <ul> * <li>Author: zhoujg | Date: 2014-3-23 下午12:56:51</li> * <li>Description: Jena语义Web编程之HelloWorld</li> * </ul> */ class HelloSemanticWeb { // FOAF命名空间 private static final String FOAF_NS = "http://xmlns.com/foaf/0.1/"; // FOAF文件绝对路径 private static final String FOAF_SCHEMA_FN = "E:/码农的世界/码农的自我修养/semantic web/workspace/foafSchema.rdf"; // myfoaf命名空间 private static final String MYFOAF_NS = "http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl"; // myfoaf文件绝对路径 private static final String MYFOAF_DATA_FN = "E:/码农的世界/码农的自我修养/semantic web/workspace/foafData.rdf"; // poeple命名空间 private static final String PEOPLE_NS = "http://www.people.com"; // people文件的绝对路径 private static final String PEOPLE_SCHEMA_FN = "E:/码农的世界/码农的自我修养/semantic web/workspace/peopleSchema.rdf"; private static final String PEOPLE_DATA_FN = "E:/码农的世界/码农的自我修养/semantic web/workspace/peopleData.rdf"; // Jena的RDF模型 private static Model friendsModel = null; // 所有本体的Schema模型 private static Model schema = null; // 推理后模型 private static InfModel inferredModel = null; public static void main(String[] args) throws IOException { version2(); } /** version 1: rdf navigate using sparql query */ public static void version1() throws IOException { System.out.println("Load my FOAF friends"); friendsModel = populateMyFOAFFriends(MYFOAF_DATA_FN); System.out.println("Say Hello to myself"); sayHelloToMyself(friendsModel); System.out.println("Say Hello to my friends"); sayHelloToMyFriends(friendsModel); } /** version 2: ontology integration using alignment */ public static void version2() throws IOException { System.out.println("Load the data"); loadABox(); System.out.println("Generate the schema to contain all ontology's tbox"); loadTBox(); // 本体对准 alignmentInTBox(); // 绑定到推理机 bindReasoner(); // 执行查询 sayHelloToMyself(inferredModel); sayHelloToMyFriends(inferredModel); } /** version 3: using jena rules */ public static void version3() throws IOException { System.out.println("Load the data"); loadABox(); System.out.println("Generate the schema to contain all ontology's tbox"); loadTBox(); // 本体对准 alignmentInTBox(); // 绑定到规则推理机 bindJenaReasoner(); // 执行查询 sayHelloToGmailFriends(inferredModel); } private static void bindJenaReasoner() { final String rule = "[gmailFriend: (?person <http://xmlns.com/foaf/0.1/mbox_sha1sum> ?email), strConcat(?email, ?lit), regex(?lit, '(.*gmail.com)')" + "-> (?person " + RDF_TYPE + " <http://www.people.com#GmailPerson>)]"; Reasoner ruleReasoner = new GenericRuleReasoner(Rule.parseRules(rule)); ruleReasoner = ruleReasoner.bindSchema(schema); inferredModel = ModelFactory.createInfModel(ruleReasoner, friendsModel); } /** 加载所有本体的ABox */ private static void loadABox() { friendsModel = ModelFactory.createDefaultModel(); InputStream is = FileManager.get().open(MYFOAF_DATA_FN);// MyFOAF的data friendsModel.read(is, MYFOAF_NS); is = FileManager.get().open(PEOPLE_DATA_FN);// people的data friendsModel.read(is, PEOPLE_NS); } /** 加载所有本体的TBox */ private static void loadTBox() { schema = ModelFactory.createDefaultModel(); InputStream is = FileManager.get().open(FOAF_SCHEMA_FN);// FOAF的Schema schema.read(is, FOAF_NS); is = FileManager.get().open(PEOPLE_SCHEMA_FN);// people的Schema schema.read(is, PEOPLE_NS); } /** 本体对准ontology alignment */ private static void alignmentInTBox() { // [1]people:Individual = foaf:Person Resource resource = schema.createResource(PEOPLE_NS + "#Individual"); Property property = schema.createProperty(OWL_URL + "equivalentClass"); Resource object = schema.createResource(FOAF_URL + "Person"); schema.add(resource, property, object); // [2]people:hasName = foaf:name resource = schema.createResource(PEOPLE_NS + "#hasName"); property = schema.createProperty(OWL_URL + "equivalentProperty"); object = schema.createResource(FOAF_URL + "name"); schema.add(resource, property, object); // [3]people:hasFriend < foaf:knows resource = schema.createResource(PEOPLE_NS + "#hasFriend"); property = schema.createProperty(RDFS_URL + "subPropertyOf"); object = schema.createResource(FOAF_URL + "knows"); schema.add(resource, property, object); // [4]myfoaf:me = people:individual_5 resource = schema.createResource(MYFOAF_NS + "#me"); property = schema.createProperty(OWL_URL + "sameAs"); object = schema.createResource(PEOPLE_NS + "#individual_5"); schema.add(resource, property, object); } private static void bindReasoner() { Reasoner reasoner = ReasonerRegistry.getOWLReasoner(); reasoner = reasoner.bindSchema(schema);// tbox inferredModel = ModelFactory.createInfModel(reasoner, friendsModel);// abox } /** 填充模型 */ private static Model fillModel(String base, String filePath) throws IOException { Model model = ModelFactory.createDefaultModel(); InputStream is = FileManager.get().open(filePath); model.read(is, base); is.close(); return model; } /** MyFOAF填充模型 */ private static Model populateMyFOAFFriends(String filePath) throws IOException { return fillModel(MYFOAF_NS, filePath); } /** RDF模型导航:SPARQL查询 - 查询自己name */ private static void sayHelloToMyself(Model model) { String query = generateMyselfSPARQLQuery(); sparql(model, query, "?name"); } private static void sayHelloToGmailFriends(Model model) { String query = generateGmailFriendsSPARQLQuery(); sparql(model, query, "?name"); } /** RDF模型导航:SPARQL查询 - 查询朋友name */ private static void sayHelloToMyFriends(Model model) { String query = generateFriendsSPARQLQuery(); sparql(model, query, "?name"); } /** 在RDF模型中执行SPARQL查询 */ private static void sparql(Model model, String query, String field) { Query q = QueryFactory.create(query); QueryExecution qexec = QueryExecutionFactory.create(q, model); System.out.println("Plan to run SPARQL query: "); System.out.println(BOUNDARY); System.out.println(query); System.out.println(BOUNDARY); ResultSet rs = qexec.execSelect(); while (rs.hasNext()) { QuerySolution qs = rs.nextSolution(); RDFNode name = qs.get(field);// 暂用RDFNode if (name != null) { System.out.println("Hello to " + name); } else { System.out.println("No friends found!"); } } qexec.close(); } private static String generateMyselfSPARQLQuery() { StringBuilder sb = generateSPARQLPREFIX(); // 添加查询语句 sb.append("SELECT DISTINCT ?name").append(NEWLINE).append("WHERE { myfoaf:me foaf:name ?name}").append(NEWLINE); return sb.toString(); } private static String generateGmailFriendsSPARQLQuery() { StringBuilder sb = generateSPARQLPREFIX(); sb.append("SELECT DISTINCT ?name WHERE {?name rdf:type people:GmailPerson}"); return sb.toString(); } private static String generateFriendsSPARQLQuery() { StringBuilder sb = generateSPARQLPREFIX(); sb.append("SELECT DISTINCT ?name").append(NEWLINE).append("WHERE { myfoaf:me foaf:knows ?friend. ").append("?friend foaf:name ?name}") .append(NEWLINE); return sb.toString(); } /** 添加SPARQL查询前缀PREFIX */ private static StringBuilder generateSPARQLPREFIX() { StringBuilder sb = new StringBuilder(); sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>").append(NEWLINE).append("PREFIX owl: <http://www.w3.org/2002/07/owl#>") .append(NEWLINE).append("PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>").append(NEWLINE) .append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>").append(NEWLINE).append("PREFIX foaf: <http://xmlns.com/foaf/0.1/>") .append(NEWLINE).append("PREFIX myfoaf: <http://blog.sina.com.cn/zhoujiagenontology/helloworld.owl#>").append(NEWLINE) .append("PREFIX people: <http://www.people.com#>").append(NEWLINE); return sb; } }
Jena语义Web开发101的更多相关文章
- 语义Web和本体开发相关技术
在技术实现方面,语义Web和本体理论的研究日趋成熟,已经有许多成熟的工具或程序接口,诸如Jena.OWL API等API是系统实现的关键技术.这里介绍系统的可行性分析以及系统开发设计的关键技术. 1 ...
- Jena 简介:通过 Jena Semantic Web Framework 在 Jave 应用程序中使用 RDF 模型
简介: RDF 越来越被认为是表示和处理半结构化数据的一种极好选择.本文中,Web 开发人员 Philip McCarthy 向您展示了如何使用 Jena Semantic Web Toolkit,以 ...
- 第五模块:WEB开发基础 第3章·BootStrap&JQuery开发
01-JQuery介绍 02-jQuery文件引入和加载的区别 03-jQuery的基础选择器 04-jQuery的层级选择器 05-jQuery的基本过滤选择器 06-jQuery的属性选择器 07 ...
- 通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? .Net Web开发技术栈
通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念 ...
- 做web开发和测试,修改hosts指定某个域名访问某个特定的IP后,如何使hosts立即生效的方法
本文转自SUN'S BLOG,原文地址:http://whosmall.com/post/143 hosts的配置方法: 在windows系统中,找到C:\windows\system32\drive ...
- Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》
首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...
- 2016 Web开发资源工具大搜罗
来源于:https://zhuanlan.zhihu.com/p/22730771 作者:余博伦链接:https://zhuanlan.zhihu.com/p/22730771来源:知乎著作权归作者所 ...
- Web开发技术发展历史
Web开发技术发展历史 来自:天码营 原文:http://www.tianmaying.com/tutorial/web-history Web的诞生 提到Web,不得不提一个词就是"互 ...
- 超全的web开发工具和资源
首页 新闻 产品 地图 动态 城市 帮助 论坛 关于 登录 注册 · 不忘初心,继续前进,环境云V2接口正式上线 · 环境云测点地图全新改版 · 祝福各位环境云用户中秋快乐! 平台信息 培训互动 ...
随机推荐
- Python namedtuple
我们都知道Python中的tuple是一个非常高效的集合对象,但是我们只能通过索引的方式访问这个集合中的元素,比如下面的代码: Bob=('bob',30,'male') print'Represen ...
- Happy Number - LeetCode
examination questions Write an algorithm to determine if a number is "happy". A happy numb ...
- javascript this在事件中的应用
this关键字在javascript中是非常强大的,但是如果你不清楚它是怎么工作的就很难使用它. function dosomething(){ this.style.color="#fff ...
- 关于js touch事件 的引用设置
一开始做前端页面的时候,接触的也是js,但是随后便被简单高效的jquery吸引过去,并一直使用至今. 而js,则被我主观的认为底层技术而抛弃. 直到这几天工作需要,研究移动端页面的触屏滑动事件,搜索j ...
- Mysql 中有关日期的函数(sql)
DAYOFWEEK(date)返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六).这些索引值对应于ODBC标准.mysql> select DAYOFWEEK('1998-0 ...
- js 仿phptrim
function trims(){ this.init = function(myarguments){ if(arguments.length===0){return false;} this.ar ...
- Deep Learning 7_深度学习UFLDL教程:Self-Taught Learning_Exercise(斯坦福大学深度学习教程)
前言 理论知识:自我学习 练习环境:win7, matlab2015b,16G内存,2T硬盘 练习内容及步骤:Exercise:Self-Taught Learning.具体如下: 一是用29404个 ...
- JMS消息中间件系列[ActiveMQ](一)
版本5.13.3的特性: 1.Supports a variety of Cross Language Clients and Protocols from Java, C, C++, C#, Rub ...
- shader函数
Intrinsic Functions (DirectX HLSL) The following table lists the intrinsic functions available in HL ...
- MySQL学习笔记--数据类型
一.数据类型(内容参考<SQL学习指南>)不完整 1.文本类型 文本类型 最大字节数 tinytext 255 text 65535 varchar 65536 mediumtext 16 ...