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

Sha*_*afi 6 java xpath rdf owl

我有一个XML文件形式的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();
Run Code Online (Sandbox Code Playgroud)

我也试过这样只提取rdfs:label元素:

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

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

请让我知道我哪里出错了.我正在使用Java XPath API.

Jos*_*lor 14

不要使用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>
Run Code Online (Sandbox Code Playgroud)

这是使用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>
Run Code Online (Sandbox Code Playgroud)

无法使用典型的XML处理技术在RDF/XML序列化中可靠地查询RDF图.

使用SPARQL查询RDF

好吧,如果我们无法用XPath可靠地查询RDF,我们应该使用什么?RDF的标准查询语言是SPARQL.RDF是基于图形的表示,SPARQL查询包括可以匹配图形的图形模式.

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

  • 第一个三元组说主题属于类型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 .                                                                                                                                                                
}
Run Code Online (Sandbox Code Playgroud)

(请注意,因为它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." |
--------------------------------------
Run Code Online (Sandbox Code Playgroud)


Sea*_*n F 2

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

"/*[local-name()='RDF']/*[local-name()='Ontology']/*[local-name()='label']/text()"
Run Code Online (Sandbox Code Playgroud)

本地名称将忽略名称空间并且将起作用(对于它找到的第一个实例)