耶拿天气数据集

    技术2024-01-05  95

    资源描述框架(RDF)最近成为W3C的推荐,与XML和SOAP等其他Web标准一起被取代。 RDF可以应用于处理临时传入数据的领域(例如CRM),并且已经广泛用于社交网络和LiveJournal和TypePad等自发布软件。

    Java程序员将具有使用RDF模型的技能,从而逐渐受益。 在本文中,我将带您了解HP Labs的开源Jena Semantic Web Framework的一些功能(请参阅参考资料 )。 您将学习如何创建和填充RDF模型,如何将其持久化到数据库中以及如何使用RDQL查询语言以编程方式查询它们。 最后,我将演示如何使用Jena的推理功能从本体论中推断有关模型的知识。

    本文假定您对RDF有所了解-包括图形,三元组和模式之类的概念-以及Java编程的基本知识。

    创建一个简单的RDF模型

    让我们从基础开始:从头开始创建模型并向其中添加RDF语句。 在本节中,我将展示如何创建一个模型来描述一组虚构的家庭成员之间的关系,如图1所示:

    图1.虚构的家谱

    你会描述使用性质不同的关系类型siblingOf , spouseOf , parentOf和childOf ,从“关系”词汇拍摄(见相关主题 )。 为简单起见,使用来自虚构名称空间http://family/ URI标识家庭成员。 词汇URI在Jena代码中经常使用,因此将它们声明为Java常量很有用,从而减少了混淆它们的风险。

    模式生成

    当使用Jena的API处理模型时,为模型词汇表中的每个属性定义常量很有用。 如果您具有词汇表的RDFS,DAML或OWL表示,Jena的Schemagen工具可以通过自动生成这些常量来简化您的生活。

    Schemagen在命令行上运行,并接受包括模式或本体文件的位置以及要输出的类的名称和Java包在内的参数。 然后可以导入生成的Java类,并使用其Property常数访问模型。

    也可以在Ant的构建过程中运行Schemagen,以使Java常量类与不断发展的词汇保持同步。

    耶拿的ModelFactory类是创建不同类型模型的首选方法。 在这种情况下,您需要一个空的内存模型,因此ModelFactory.createDefaultModel()是要调用的方法。 此方法返回Model的实例,您将使用该实例创建代表家庭中每个人的Resource 。 创建资源后,可以对它们进行声明并添加模型。

    在耶拿(Jena)中,语句的主题始终是Resource ,谓词由Property表示,而对象是另一个Resource或文字值。 文字在耶拿用Literal类型表示。 所有这些类型共享一个公共接口RDFNode 。 您将需要四个不同的Property实例来表示家族树中的关系。 这些实例是使用Model.createProperty()创建的。

    向模型添加语句的最简单方法是调用Resource.addProperty() 。 此方法在模型中创建一个以“ Resource为主题的语句。 该方法有两个参数,一个表示语句谓词的Property和该语句的对象。 addProperty()方法已重载:一个重载将RDFNode作为对象,因此可以使用Resource或Literal 。 还有一些方便重载,它们采用Java原语或String表示的文字。 在该示例中,语句的对象是Resource代表其他家庭成员。

    通过调用带有三元组的主题,谓词和对象的Model.createStatement() ,也可以在模型上直接创建语句。 请注意,以这种方式创建一个Statement不会将其添加到模型中。 如果要将其添加到模型中,请使用创建的Statement调用Model.add() ,如清单1所示:

    清单1.创建一个代表虚构家庭的模型
    // URI declarations String familyUri = "http://family/"; String relationshipUri = "http://purl.org/vocab/relationship/"; // Create an empty Model Model model = ModelFactory.createDefaultModel(); // Create a Resource for each family member, identified by their URI Resource adam = model.createResource(familyUri+"adam"); Resource beth = model.createResource(familyUri+"beth"); Resource chuck = model.createResource(familyUri+"chuck"); Resource dotty = model.createResource(familyUri+"dotty"); // and so on for other family members // Create properties for the different types of relationship to represent Property childOf = model.createProperty(relationshipUri,"childOf"); Property parentOf = model.createProperty(relationshipUri,"parentOf"); Property siblingOf = model.createProperty(relationshipUri,"siblingOf"); Property spouseOf = model.createProperty(relationshipUri,"spouseOf"); // Add properties to adam describing relationships to other family members adam.addProperty(siblingOf,beth); adam.addProperty(spouseOf,dotty); adam.addProperty(parentOf,edward); // Can also create statements directly . . . Statement statement = model.createStatement(adam,parentOf,fran); // but remember to add the created statement to the model model.add(statement);

    完整的代码示例FamilyModel.java还演示了如何将批处理语句立即作为数组或java.util.List添加到模型java.util.List 。

    建立家庭模型后,让我们看看如何使用Jena的查询API从信息中提取信息。

    询问RDF模型

    以编程方式询问Jena模型主要是通过Model和Resource接口上的list()方法执行的。 这些方法可用于获取与某些条件匹配的主题,对象和Statement 。 它们还返回java.util.Iterator ,它具有返回特定对象类型的额外方法。

    让我们回到清单1的家庭模型示例,看看可以如何查询它,如清单2所示:

    清单2.查询族模型
    // List everyone in the model who has a child: ResIterator parents = model.listSubjectsWithProperty(parentOf); // Because subjects of statements are Resources, the method returned a ResIterator while (parents.hasNext()) { // ResIterator has a typed nextResource() method Resource person = parents.nextResource(); // Print the URI of the resource System.out.println(person.getURI()); } // Can also find all the parents by getting the objects of all "childOf" statements // Objects of statements could be Resources or literals, so the Iterator returned // contains RDFNodes NodeIterator moreParents = model.listObjectsOfProperty(childOf); // To find all the siblings of a specific person, the model itself can be queried NodeIterator siblings = model.listObjectsOfProperty(edward, siblingOf); // But it's more elegant to ask the Resource directly // This method yields an iterator over Statements StmtIterator moreSiblings = edward.listProperties(siblingOf);

    最通用的查询方法是Model.listStatements(Resource s, Property p, RDFNode o) ,是在此演示的便捷方法的基础。 这些参数中的任何一个都可以保留为null ,在这种情况下,它们可以用作通配符,匹配任何内容。 清单3显示了一些Model.listStatements()用法的示例:

    清单3.使用选择器查询模型
    // Find the exact statement "adam is a spouse of dotty" model.listStatements(adam,spouseOf,dotty); // Find all statements with adam as the subject and dotty as the object model.listStatements(adam,null,dotty); // Find any statements made about adam model.listStatements(adam,null,null); // Find any statement with the siblingOf property model.listStatements(null,siblingOf,null);

    导入和保留模型

    并非所有应用程序都将以空模型开头。 更常见的是,在启动时会从现有数据中填充模型。 在这种情况下使用内存模型的缺点是,每次启动应用程序时,都必须从头开始重新填充模型。 此外,每次关闭应用程序时,对内存模型所做的任何更改都将丢失。

    一种解决方案是使用Model.write()将模型序列化到文件系统,并使用Model.read()在启动时反序列化它。 但是,Jena还提供了持久化模型,这些模型被连续透明地持久化到后备存储中。 Jena可以将其模型持久保存在文件系统或关系数据库中。 当前支持的数据库引擎是PostgreSQL,Oracle和MySQL。

    词网

    WordNet是“英语词汇数据库”。 我正在使用的RDF表示形式是Sergey Melnik和Stefan Decker编写的。 它有四个单独的模型,您将在本文的示例中使用其中三个。

    WordNet名词模型包含WordNet表示的所有“词汇概念”,以及用来表示每个词的“单词形式”。 例如,它包含一个词汇概念,由单词形式“家犬”,“狗”和“犬科动物”表示。

    第二个模型是WordNet词汇表。 它提供了模型中每个词汇概念的简要定义。 “狗”的词汇概念有一个词汇表条目,指出“自史前时代以来,人就已经驯养了犬属(可能是普通狼的后代)的成员”。

    WordNet的同义词是第三个模型。 它定义了模型中概念的层次结构。 “狗”概念是“犬”概念的下位词,“犬”本身是“食肉动物”概念的下位词。

    为了演示如何导入和持久化模型,我将以WordNet 1.6数据库的RDF表示形式导入MySQL。 因为我使用的WordNet表示形式采用几个单独的RDF文档的形式,所以将它们导入到单个Jena模型中会合并它们的语句。 图2展示了将名词和词汇表模型合并在一起后,WordNet模型的片段结构:

    图2.合并的WordNet名词和词汇表模型的结构

    创建数据库支持的模型的第一步是实例化MySQL驱动程序类,并创建一个DBConnection实例。 DBConnection构造函数使用用户的ID和密码来登录数据库。 它还带有一个数据库URL参数,该参数包含Jena要使用的MySQL数据库的名称,格式为"jdbc:mysql://localhost/dbname" 。 Jena可以在一个数据库中创建多个模型。 最终的DBConnection参数是数据库类型,对于MySQL来说是"MySQL" 。

    然后,可以将DBConnection实例与Jena的ModelFactory一起使用,以创建数据库支持的模型。

    一旦创建了模型,就可以从文件系统中读取WordNet RDF文档。 各种Model.read()方法可以从Reader , InputStream或URL填充模型。 可以从Notation3,N-Triples或默认情况下从RDF / XML语法解析模型。 WordNet模型已序列化为RDF / XML,因此您无需指定语法。 读取模型时,可以提供基本URI。 基本URI用于将模型中的任何相对URI转换为绝对URI。 由于WordNet文档不包含任何相对URI,因此可以将此参数指定为null 。

    清单4显示了将WordNet RDF / XML文件导入到MySQL持久模型中的完整过程:

    清单4.导入和保留WordNet模型
    // Instantiate the MySQL driver Class.forName("com.mysql.jdbc.Driver"); // Create a database connection object DBConnection connection = new DBConnection(DB_URL, DB_USER, DB_PASSWORD, DB_TYPE); // Get a ModelMaker for database-backed models ModelMaker maker = ModelFactory.createModelRDBMaker(connection); // Create a new model named "wordnet." Setting the second parameter to "true" causes an // AlreadyExistsException to be thrown if the db already has a model with this name Model wordnetModel = maker.createModel("wordnet",true); // Start a database transaction. Without one, each statement will be auto-committed // as it is added, which slows down the model import significantly. model.begin(); // For each wordnet model . . . InputStream in = this.getClass().getClassLoader().getResourceAsStream(filename); model.read(in,null); // Commit the database transaction model.commit();

    现在已经填充了wordnet模型,您可以稍后通过调用ModelMaker.openModel("wordnet",true);来访问它ModelMaker.openModel("wordnet",true);

    仅使用Jena的API来查询与WordNet一样大和丰富的模型将是限制性的,因为要执行的每种查询类型都需要编写几行定制代码。 幸运的是,Jena提供了一种以RDQL形式表达通用查询的机制。

    RDF数据查询语言(RDQL)

    RDQL是RDF的查询语言。 尽管尚未成为正式标准,但RDQL已由RDF框架广泛实施。 RDQL允许查询引擎执行访问数据模型的艰苦工作,从而简洁地表达复杂的查询。 RDQL的语法从表面上类似于SQL的语法,实际上,使用关系数据库查询的任何人都会熟悉它的某些概念。 可以在Jena网站上找到出色的RDQL教程,但是一些简短的示例对说明基础知识大有帮助。

    可以使用jena.rdfquery工具针对Jena模型在命令行上执行RDQL查询。 RDFQuery从文本文件获取RDQL查询,并针对指定的模型运行它。 要针对数据库支持的模型运行,需要几个参数。 清单5显示了运行以下示例所需的完整命令行:

    清单5.从命令行运行RDQL查询
    $java jena.rdfquery --data jdbc:mysql://localhost/jena --user dbuser --password dbpass --driver com.mysql.jdbc.Driver --dbType MySQL --dbName wordnet --query example_query.rdql

    如您所见,大多数这些参数提供了创建与MySQL的连接所需的详细信息。 重要的部分是--query example_query.rdql ,它是RDQL文件的位置。 还要注意,运行jena.rdfquery需要Jena的lib目录中的所有JAR文件。

    清单6显示了您将检查的第一个查询:

    清单6. RDQL查询以查找“本地狗”的WordNet词汇表条目
    SELECT ?definition WHERE (?concept, <wn:wordForm>, "domestic dog"), (?concept, <wn:glossaryEntry>, ?definition) USING wn FOR <http://www.cogsci.princeton.edu/~wn/schema/>

    SELECT部分声明要由查询输出的变量-在本例中为名为definition的变量。 WHERE子句引入了第二个变量concept ,并定义了与图匹配的三元组。 该查询在图中找到WHERE子句中所有三元组均成立的语句。 因此,用英语来说, WHERE子句类似于“找到带有“家犬”作为词形的概念,并找到这些概念的词汇表条目”之类的东西,如图3所示USING子句是一种便利,用于声明命名空间的前缀。

    图3.与清单6中的WHERE子句匹配的图

    运行查询结果为:

    definition =============================================================================== "a member of the genus Canis (probably descended from the common wolf) that has been domesticated by man since prehistoric times; occurs in many breeds; "the dog barked all night""

    因此,在这种情况下只有一个结果。 清单7中显示的下一个查询说:“查找以单词“ bear”代表的概念,并找到这些概念的词汇表条目。

    清单7. RDQL查询以查找“ bear”的WordNet词汇表条目
    SELECT ?definition WHERE (?concept, <wn:wordForm>, "bear"), (?concept, <wn:glossaryEntry>, ?definition) USING wn FOR <http://www.cogsci.princeton.edu/~wn/schema/>

    该查询返回15个结果,因为此字形代表几个不同的概念。 结果开始:

    definition =============================================================================== "massive plantigrade carnivorous or omnivorous mammals with long shaggy coats and strong claws" "an investor with a pessimistic market outlook" "have on one's person; "He wore a red ribbon"; "bear a scar"" "give birth (to a newborn); "My wife had twins yesterday!""

    清单8中显示了一个更复杂的示例,它找到另外两个示例的上位词(父词):

    清单8. RDQL查询以找到“ panther”和“ tiger”的WordNet上位词
    SELECT ?wordform, ?definition WHERE (?firstconcept, <wn:wordForm>, "panther"), (?secondconcept, <wn:wordForm>, "tiger"), (?firstconcept, <wn:hyponymOf>, ?hypernym), (?secondconcept, <wn:hyponymOf>, ?hypernym), (?hypernym, <wn:wordForm>, ?wordform), (?hypernym, <wn:glossaryEntry>, ?definition) USING wn FOR <http://www.cogsci.princeton.edu/~wn/schema/>

    在这里,查询显示为“找到单词'panther'和'tiger'所指的概念,找到第三个概念,其中前两个是下义词,并找到该概念的可能单词和词汇表条目”,如图所示在图4中:

    图4.清单8中的WHERE子句匹配的图

    在SELECT子句中都声明了wordform和definition ,因此都将其输出。 尽管此查询仅匹配单个WordNet概念,但查询的图形可以两种方式匹配,因为该概念具有两种不同的字形:

    wordform | definition ===================================================================================== "big cat" | "any of several large cats typically able to roar and living in the wild" "cat" | "any of several large cats typically able to roar and living in the wild"

    在耶拿使用RDQL

    Jena的com.hp.hpl.jena.rdql软件包包含在Java代码中使用RDQL所需的所有类和接口。 要创建RDQL查询,请将RDQL放入String ,然后将其传递给Query的构造函数。 通常,除非在RDQL本身中使用FROM子句另外指定,否则显式设置模型以用作查询源。 准备好Query , QueryEngine可以从中创建一个QueryEngine并执行查询。 清单9演示了此过程:

    清单9.创建和运行RDQL查询
    // Create a new query passing a String containing the RDQL to execute Query query = new Query(queryString); // Set the model to run the query against query.setSource(model); // Use the query to create a query engine QueryEngine qe = new QueryEngine(query); // Use the query engine to execute the query QueryResults results = qe.exec();

    与Query一起使用的一种有用技术是在执行之前将其某些变量设置为固定值。 此用法模式类似于javax.sql.PreparedStatement用法。 变量通过ResultBinding对象绑定到值,该对象在执行时传递给QueryEngine 。 可以将变量绑定到Jena Resource或文字值。 在将文字绑定到变量之前,将其包装为对Model.createLiteral的调用。 清单10说明了预绑定方法:

    清单10.将查询变量绑定到值
    // Create a query that has variables x and y Query query = new Query(queryString); // A ResultBinding specifies mappings between query variables and values ResultBinding initialBinding = new ResultBinding() ; // Bind the query's first variable to a resource Resource someResource = getSomeResource(); initialBinding.add("x", someResource); // Bind the query's second variable to a literal value RDFNode foo = model.createLiteral("bar"); initialBinding.add("y", foo); // Execute the query with the specified values for x and y QueryEngine qe = new QueryEngine(query); QueryResults results = qe.exec(initialBinding);

    QueryEngine.exec()返回的QueryResults对象实现java.util.Iterator 。 它的next()方法返回ResultBinding对象。 可以从ResultBinding按名称获取查询中使用的所有变量,无论它们是否是SELECT子句的一部分。 清单11显示了如何执行此操作,再次使用清单6中的RDQL查询:

    清单11. RDQL查询以查找“本地狗”的WordNet词汇表条目
    SELECT ?definition WHERE (?concept, <wn:wordForm>, "domestic dog"), (?concept, <wn:glossaryEntry>, ?definition) USING wn FOR <http://www.cogsci.princeton.edu/~wn/schema/>";

    通过运行此查询获得的ResultBinding如预期的那样包含该单词的文字词汇表条目。 另外,您可以访问变量concept 。 通过调用ResultBinding.get()按名称获取变量。 此方法返回的所有变量都可以RDFNode为RDFNode ,如果要将它们重新绑定到另一个RDQL查询中,这将非常有用。

    在这种情况下, concept变量表示RDF资源,因此从ResultBinding.get()获得的Object可以ResultBinding.get()为Resource 。 然后可以调用Resource的查询方法以进一步探索模型的这一部分,如清单12所示:

    清单12.处理查询结果
    // Execute a query QueryResults results = qe.exec(); // Loop over the results while (results.hasNext()) { ResultBinding binding = (ResultBinding)results.next(); // Print the literal value of the "definition" variable RDFNode definition = (RDFNode) binding.get("definition"); System.out.println(definition.toString()); // Get the RDF resource used in the query Resource concept = (Resource)binding.get("concept"); // Query the concept directly to find other wordforms it has List wordforms = concept.listObjectsOfProperty(wordForm); }

    FindHypernym.java包含在源文件下载(请参阅该程序相关信息 ),总结你在这里看到的区域。 它使用清单13中所示的查询查找命令行中给出的单词的上位词:

    清单13. RDQL查询以查找概念的上位词的字形和词汇表条目
    SELECT ?hypernym, ?definition WHERE (?firstconcept, <wn:wordForm>, ?hyponym), (?firstconcept, <wn:hyponymOf>, ?secondconcept), (?secondconcept, <wn:wordForm>, ?hypernym), (?secondconcept, <wn:glossaryEntry>, ?definition) USING wn FOR <http://www.cogsci.princeton.edu/~wn/schema/>

    命令行上给定的单词与下hyponym词绑定,查询会找到该词代表的概念,找到第一个概念为下义词的第二个概念,然后输出该概念的字形和定义。 清单14显示了它的输出:

    清单14.运行示例FindHypernym程序
    $ java FindHypernym "wisteria" Hypernyms found for 'wisteria': vine: weak-stemmed plant that derives support from climbing, twining, or creeping along a surface

    用OWL添加含义

    您可能想知道为什么搜索“紫藤”的上位词只会返回其直接上位词“藤”。 如果您植物学上的想法,您可能还希望“微量营养体”显示为上调,当然还有“植物”。 确实,WordNet模型说“紫藤”是“藤”的下义词,“藤”是“微量营养体”的下义词。 凭直觉,您知道“紫藤”因此是“示营养体”的下义词,因为您知道“关系的别名”是可传递的 。 因此,您需要一种将这些知识整合到FindHypernym程序中的方法,这是OWL的所在。

    传递关系

    的关系是可传递的三种元素- 的a,b,和c -使得a与b之间的关系的存在,和b和c之间,意味着A和C之间的关系的存在。

    传递关系的一个示例是“大于”:如果a大于b ,并且b大于c ,则得出a必须大于c的结论。

    Web本体语言或OWL是W3C建议书,旨在“明确表示词汇中术语的含义以及这些术语之间的关系”。 OWL与RDF Schema一起提供了一种正式描述RDF模型内容的机制。 除了定义资源可以属于的分层类之外,OWL还允许表达资源属性的特征。 例如,在所使用的关系词汇清单1 ,OWL可以用于状态下childOf属性是的逆parentOf属性。 另一个示例是声明WordNet词汇表的hyponymOf属性是可传递的。

    在耶拿(Jena)中,本体被视为一种特殊的RDF模型OntModel 。 该接口允许使用编程方法来操纵本体,并使用方便的方法来创建类,属性限制等。 另一种方法是将本体视为常规RDF模型,并简单地添加定义其语义规则的语句。 清单15中演示了这两种技术。注意,还可以向现有数据模型中添加本体声明,或者使用Model.union()将本体模型与数据模型合并。

    清单15.为WordNet创建OWL本体模型
    // Make a new model to act as an OWL ontology for WordNet OntModel wnOntology = ModelFactory.createOntologyModel(); // Use OntModel's convenience method to describe // WordNet's hyponymOf property as transitive wnOntology.createTransitiveProperty(WordnetVocab.hyponymOf.getURI()); // Alternatively, just add a statement to the underlying model to express that // hyponymOf is of type TransitiveProperty wnOntology.add(WordnetVocab.hyponymOf, RDF.type, OWL.TransitiveProperty);

    与耶拿的推论

    给定一个本体和一个模型,Jena的推理引擎可以导出该模型未明确表达的其他语句。 耶拿(Jena)提供了几种Reasoner类型,以与不同类型的本体一起使用。 因为您要在WordNet模型中使用OWL本体,所以需要OWLReasoner 。

    下面的示例显示如何将OWL WordNet本体应用于WordNet模型本身以创建推理模型。 我实际上将在这里使用WordNet模型的子集,仅包含下义词层次结构中“植物生命”下的那些名词。 仅使用子集的原因是,推理模型需要保存在内存中,而WordNet模型太大,无法使用内存模型。 我用来提取从全共发现模型植物模型的代码包含在本文的源代码,并命名为ExtractPlants.java(参见相关主题 )。

    首先,我将从ReasonerRegistry获得一个OWLReasoner 。 ReasonerRegistry.getOWLReasoner()以其标准配置返回OWL推理程序,对于这种简单情况而言,这是很好的。 下一步是将推理机绑定到WordNet本体。 此操作将返回准备应用本体规则的推理机。 接下来,我将使用绑定推理InfModel从WordNet模型创建InfModel 。

    从原始数据和OWL本体创建推理模型后,就可以像对待其他任何Model实例一样对待它。 因此,如清单16所示,可以将FindHypernym.java与常规Jena模型一起使用的Java代码和RDQL查询重新应用于推理模型,而无需进行任何更改:

    清单16.创建和查询推理模型
    // Get a reference to the WordNet plants model ModelMaker maker = ModelFactory.createModelRDBMaker(connection); Model model = maker.openModel("wordnet-plants",true); // Create an OWL reasoner Reasoner owlReasoner = ReasonerRegistry.getOWLReasoner(); // Bind the reasoner to the WordNet ontology model Reasoner wnReasoner = owlReasoner.bindSchema(wnOntology); // Use the reasoner to create an inference model InfModel infModel = ModelFactory.createInfModel(wnReasoner, model); // Set the inference model as the source of the query query.setSource(infModel); // Execute the query as normal QueryEngine qe = new QueryEngine(query); QueryResults results = qe.exec(initialBinding);

    完整的清单可在文章源中找到,名为FindInferredHypernyms.java。 清单17显示了在查询模型中查询“紫藤”的上位词时发生的情况:

    清单17.运行示例FindInferredHypernyms程序
    $ java FindInferredHypernyms wisteria Hypernyms found for 'wisteria': vine: weak-stemmed plant that derives support from climbing, twining, or creeping along a surface tracheophyte: green plant having a vascular system: ferns, gymnosperms, angiosperms vascular plant: green plant having a vascular system: ferns, gymnosperms, angiosperms plant life: a living organism lacking the power of locomotion flora: a living organism lacking the power of locomotion plant: a living organism lacking the power of locomotion

    OWL本体中包含的信息使Jena可以推断出“紫藤”在整个模型中都有上位词。

    摘要

    本文展示了Jena Semantic Web Toolkit的一些最重要的功能,并通过示例展示了如何创建,导入和保留RDF模型。 您还研究了查询模型的不同方法,并了解了如何使用RDQL简洁表达任意查询。 此外,您已经了解了如何使用Jena的推理引擎对基于本体的模型进行推理。

    本文中的示例演示了将数据表示为RDF模型的某些功能,以及RDQL从中提取数据的灵活性。 在您自己的Java应用程序中使用RDF模型时,此处说明的基本方法将是一个有用的起点。

    Jena是一个全面的RDF工具集,其功能超出了您在此处学到的知识。 耶拿项目的主页是开始学习更多有关其功能的好地方。


    翻译自: https://www.ibm.com/developerworks/java/library/j-jena/index.html

    相关资源:jena_climate_2009_2016耶拿天气数据集
    Processed: 0.009, SQL: 10