如何在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]
的三元组。 两个三元组都有相同的主题。
- 第一个三元组说,这个主题是types
owl: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 ,这解释了如何完成它。