如何在Java中使用XPath访问OWL文档?

我有一个XML文件forms的OWL文档。 我想从这个文档中提取元素。 我的代码适用于简单的XML文档,但不适用于OWL XML文档。

实际上我正在寻找这个元素: /rdf:RDF/owl:Ontology/rdfs:label ,为此我做了这个:

  DocumentBuilder builder = builderfactory.newDocumentBuilder(); Document xmlDocument = builder.parse( new File(XpathMain.class.getResource("person.xml").getFile())); XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance(); XPath xPath = factory.newXPath(); XPathExpression xPathExpression = xPath.compile("/rdf:RDF/owl:Ontology/rdfs:label/text()"); String nameOfTheBook = xPathExpression.evaluate(xmlDocument,XPathConstants.STRING).toString(); 

我也尝试以这种方式只提取rdfs:label元素:

  XPathExpression xPathExpression = xPath.compile("//rdfs:label"); NodeList nodes = (NodeList) xPathExpression.evaluate(xmlDocument, XPathConstants.NODESET); 

但是这个节点列表是空的。

请让我知道我要去哪里错了。 我正在使用Java XPath API。

因为xpath不知道你正在使用的命名空间。 尝试使用:

 "/*[local-name()='RDF']/*[local-name()='Ontology']/*[local-name()='label']/text()" 

本地名称将忽略名称空间并将工作(对于它find的第一个实例)

不要用XPath查询RDF(或OWL)

已经有了一个可以接受的答案,但是我想详细阐述@迈克尔对这个问题的评论 。 尝试使用RDF作为XML(因此,OWL本体的RDF序列化)是一个非常糟糕的主意,其原因很简单:相同的RDF图可以序列化为许多不同的XML文档。 在这个问题中,所有被要求的是owl:Ontology rdfs:label owl:Ontology元素,那么多less可能会出错? 那么,这里有两个本体的序列化。

第一个是相当人类可读的,当我使用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编码中可用特性较less的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查询包括可以匹配graphics的graphics模式。

在这种情况下,我们想在图中匹配的模式由两个三元组组成。 三元组是forms[subject,predicate,object]的三元组。 两个三元组都有相同的主题。

  • 第一个三元组说,这个主题是typesowl:Ontology 。 关系“types”是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 .简写formss p1 o1 . s p2 o2 . 。。)

您可以以编程方式或使用命令行工具在Jena中针对您的模型运行SPARQL查询。 如果你以编程的方式来做,结果是相当容易的。 为了确认这个查询得到了我们感兴趣的值,我们可以使用Jena的命令行arq来testing它。

 $ arq --data labelledOnt.owl --query getLabel.sparql -------------------------------------- | label | ====================================== | "Here is a label on the Ontology." | -------------------------------------- 

如果您为自己实现javax.xml.namespace.NamespaceContext ,则可以在查询中使用名称空间。 请看看这个答案https://stackoverflow.com/a/5466030/1443529 ,这解释了如何完成它。