不要使用 XPath 查询 RDF(或 OWL)
已经有一个公认的答案,但我想详细说明@Michael对这个问题的评论。尝试将 RDF 作为 XML 使用(因此,OWL 本体的 RDF 序列化)是一个非常糟糕的主意,其原因非常简单:同一个 RDF 图可以序列化为许多不同的 XML 文档。在这个问题中,所有被要求的都是rdfs:label
一个owl:Ontology
元素,那么有多少可能会出错?好吧,这是本体的两个序列化。
第一个是人类可读的,它是在我使用 Protégé 本体编辑器保存本体时由 OWL API 生成的。我认为,接受的答案中的查询可以解决这个问题。
<rdf:RDF xmlns="http://www.example.com/labelledOnt#"
xml:base="http://www.example.com/labelledOnt"
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.example.com/labelledOnt">
<rdfs:label>Here is a label on the Ontology.</rdfs:label>
</owl:Ontology>
</rdf:RDF>
这是使用较少 RDF/XML 编码中可用的花哨功能的相同RDF 图。这是相同的 RDF 图,因此也是相同的OWL 本体。但是,这里没有 owl:Ontology
XML 元素,XPath 查询将失败。
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns="http://www.example.com/labelledOnt#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" >
<rdf:Description rdf:about="http://www.example.com/labelledOnt">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
<rdfs:label>Here is a label on the Ontology.</rdfs:label>
</rdf:Description>
</rdf:RDF>
您不能使用典型的 XML 处理技术可靠地查询 RDF/XML 序列化中的 RDF 图。
使用 SPARQL 查询 RDF
好吧,如果我们不能用 XPath 可靠地查询 RDF,我们应该使用什么?RDF 的标准查询语言是SPARQL。RDF 是一种基于图的表示,SPARQL 查询包括可以匹配图的图模式。
在这种情况下,我们想要在图中匹配的模式由两个三元组组成。三元组是一个 3 元组的形式[subject,predicate,object]
。两个三元组都有相同的主题。
- 第一个三元组表示主题是 type
owl:Ontology
。关系“是类型”是rdf:type
,所以第一个三元组是[?something,rdf:type,owl:Ontology]
。
- 第二个三元组表示主题(现在已知是一个本体)有一个
rdfs:label
,这就是我们感兴趣的值。对应的三元组是[?something,rdfs:label,?label]
。
在 SPARQL 中,定义必要的前缀后,我们可以编写以下查询。
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?label WHERE {
?ontology a owl:Ontology ;
rdfs:label ?label .
}
(请注意,因为rdf:type
很常见,所以 SPARQL 包含a
它作为它的缩写。该符号s p1 o1; p2 o2 .
只是两个三元组模式的简写s p1 o1 . s p2 o2 .
。)
您可以通过编程方式或使用命令行工具对 Jena 中的模型运行 SPARQL 查询。如果您以编程方式执行此操作,则很容易得出结果。为了确认这个查询得到了我们感兴趣的值,我们可以使用 Jena 的命令行arq
来测试它。
$ arq --data labelledOnt.owl --query getLabel.sparql
--------------------------------------
| label |
======================================
| "Here is a label on the Ontology." |
--------------------------------------