wiki地址:http://protegewiki.stanford.edu/wiki/BuildingSemanticWebApplications
Main article: ProtegeOWL_API_Programmers_Guide
Building Semantic Web Applications--搭建语义网应用程序
可以使用Protege-OWL API 构建独立的应用程序。这些应用程序可以从语义网(Semantic Web)上下载本体,对这些本体进行查询或者编辑,对实例和类进行归纳划分,并且将结果本体写入文件中。语义网应用的一些方法和架构由Holger Knublanch在他的论文中提出。下面的图是从论文中截取的,主要描述了一个应用的典型架构。
上图的架构,将整个应用系统划分为两个部分:语义网层,逻辑层
语义网层:存储大量可用的领域本体,其他用户可以使用web Service获取网络上的本体。
逻辑层:将使用的本体封装成应用中对应的具体java类(针对应用构建模型),底层拥有各种推理机可以进行推理。这里可以这么理解,将语义网理解成一个巨大的数据库,而图中Customer.java和Activity.java可以理解成我们平时的应用中的Model。
其实这里还隐藏了一个与用户的交互层,即View。使用Jsp编写,通过web service或者servlet等方式调用逻辑层提供的服务。
Wiki中给出了下面的例子:
1. 有一个Purchase本体,每个purchase包含了customer和product(这两个概念定义在别的本体中)。
2. 我们需要处理某个customer,则直接调用本体的代码如下。
OWLNamedClass customerClass = owlModel.getOWLNamedClass("Customer");
OWLDatatypeProperty firstNameProperty = owlModel.getOWLDatatypeProperty("firstName");
OWLIndividual myCustomer = owlModel.getOWLIndividual("Customer42");
String firstName = (String) myCustomer.getPropertyValue(firstNameProperty);
这种调用方式容易造成混乱,直接通过字符串处理本体是非常不合理的。
如果我们需要统计用户的个数,则代码如下
private static float getPurchasesSum(RDFIndividual customer) {
OWLModel owlModel = customer.getOWLModel();
float sum = 0;
RDFProperty purchasesProperty = owlModel.getRDFProperty("purchases");
RDFProperty productProperty = owlModel.getRDFProperty("product");
RDFProperty priceProperty = owlModel.getRDFProperty("price");
Iterator purchases = customer.listPropertyValues(purchasesProperty);
while(purchases.hasNext()) {
RDFIndividual purchase = (RDFIndividual) purchases.next();
RDFIndividual product = (RDFIndividual) purchase.getPropertyValue(productProperty);
Float price = (Float) product.getPropertyValue(priceProperty);
sum += price.floatValue();
}
return sum;
}
3. 封装为应用的model
编写一个接口,完成Customer需要的功能,向外部应用提供这样的接口可以提高程序的安全性,也符合面向对象的原则。
public interface Customer {
String getFirstName();
void setFirstName(String value);
...
float getPurchasesSum();
}
编写一个默认用户类,实现这些方法。每个用户是本体中的一个实例,所以该类可以从api提供的本体实例类继承。
package com.demo.model.impl;
public class DefaultCustomer extends DefaultOWLIndividual implements Customer {
public DefaultCustomer(KnowledgeBase kb, FrameID id) {
super(kb, id);
}
public String getFirstName() {
RDFProperty property = getOWLModel().getRDFProperty("firstName");
return (String) getPropertyValue(property);
}
public void setFirstName(String value) {
RDFProperty property = getOWLModel().getRDFProperty("firstName");
setPropertyValue(property, value);
}
}
另外,编写一个工厂类MyFactory用于实现向本体中添加新的数据。
package edu.stanford.smi.protegex.owlx.examples.javaDemo.model;
import edu.stanford.smi.protegex.owl.model.OWLModel;
import edu.stanford.smi.protegex.owl.model.RDFSNamedClass;
/**
* Generated by Protégé-OWL (http://protege.stanford.edu/plugins/owl).
*
* @version generated on Mon Feb 21 10:53:08 EST 2005
*/
public class MyFactory {
private OWLModel owlModel;
public MyFactory(OWLModel owlModel) {
this.owlModel = owlModel;
}
public RDFSNamedClass getCustomerClass() {
final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Customer";
final String name = owlModel.getResourceNameForURI(uri);
return owlModel.getRDFSNamedClass(name);
}
public Customer createCustomer(String name) {
final RDFSNamedClass cls = getCustomerClass();
return (Customer) cls.createInstance(name).as(Customer.class);
}
public RDFSNamedClass getPurchaseClass() {
final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Purchase";
final String name = owlModel.getResourceNameForURI(uri);
return owlModel.getRDFSNamedClass(name);
}
public Purchase createPurchase(String name) {
final RDFSNamedClass cls = getPurchaseClass();
return (Purchase) cls.createInstance(name).as(Purchase.class);
}
public RDFSNamedClass getProductClass() {
final String uri = "http://www.owl-ontologies.com/javaDemo.owl#Product";
final String name = owlModel.getResourceNameForURI(uri);
return owlModel.getRDFSNamedClass(name);
}
public Product createProduct(String name) {
final RDFSNamedClass cls = getProductClass();
return (Product) cls.createInstance(name).as(Product.class);
}
}
4. 改进后
可以直接使用提供的接口对本体中的用户进行操作,整个代码结构非常清晰简洁。
private static Purchase createPurchase(Customer customer, Product product, String date) {
OWLModel owlModel = customer.getOWLModel();
Purchase purchase = new MyFactory(owlModel).createPurchase(null);
purchase.setCustomer(customer);
purchase.setProduct(product);
RDFSDatatype xsdDate = owlModel.getRDFSDatatypeByName("xsd:date");
purchase.setDate(owlModel.createRDFSLiteral(date, xsdDate);
return purchase;
}
这是一个简单应用的基本框架。最近也正好在做本体相关的工作,但是应用中出现的类和实例非常之多,主要涉及的也是推理的工作,真正直接对本体各个数据进行直接改动的工作还是比较少。但是这个思维方式还是非常值得借鉴的,觉得很经典,其实也很像MVC。在后续的工作中或许也会涉及到这样的应用,这里先初步学习记录。