【问题标题】:How to get Individual name from Node value in Jena RDF Inf Model如何从 Jena RDF Inf 模型中的节点值获取个人名称
【发布时间】:2015-01-19 09:34:33
【问题描述】:

我在从 Jena 图中提取个人姓名时遇到问题(具有通用规则推理器和 OntSpec 的 RDF 推理模型是 RDFS_MEM_RDFS_INF )。这可能是一个简单的案例,但我无法在网上找到合适的教程来完成这项工作(耶拿规则的新手)。在这种情况下调用什么正确的 api?

infStmts = pModel.listStatements().filterKeep( new Filter<Statement>() {
        @Override
        public boolean accept(Statement o) {                
            boolean ex = false;
            Property prop1 = pModel.getProperty(prefix + "hasPropertyP1");
            String predicateName  = o.asTriple().getPredicate().getLocalName();             
            if(predicateName.equalsIgnoreCase(prop1.getLocalName()) )                   
                ex = true;                
            return ex;

        }
    });

    Statement s = infStmts.next();
    Statement st = ResourceFactory.createStatement(s.getSubject(), s.getPredicate(), s.getObject());
    System.out.println(st.getSubject().toString() + "****" + pModel.getRDFNode(st.getSubject().asNode()).as(Individual.class));
Exception in thread "Thread-37" com.hp.hpl.jena.ontology.ConversionException: Cannot convert node 4e62503a:14b01762f42:-7eea to Individual
at com.hp.hpl.jena.ontology.impl.IndividualImpl$1.wrap(IndividualImpl.java:61)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:152)
at com.hp.hpl.jena.enhanced.EnhNode.convertTo(EnhNode.java:31)
at com.hp.hpl.jena.enhanced.Polymorphic.asInternal(Polymorphic.java:62)
at com.hp.hpl.jena.enhanced.EnhNode.as(EnhNode.java:107)
...

耶拿规则文件有以下规则

[rule: ( :Subject1 :hasPropertyP2 :Object1) ->
       ( ?x rdf:type :Class1)
       ( ?x :hasPropertyP1 :Object2)]

我需要 ?x 的个人姓名值

【问题讨论】:

  • “个人姓名”是什么意思?指定个人的 IRI? rdfs:label 属性的值?还有什么?
  • 是的,指定个人的 IRI 是我想要的。
  • 据我了解,空白节点 (en.wikipedia.org/wiki/Blank_node) 4e62503a:14b01762f42:-7eea 持有满足规则的所需个人集合,因此我想检索包含的数据在这种情况下是那些具有 hasPropertyP1 或要编写 jena 规则的个人的数据,以便与 sparql 查询类似地检索个人
  • "空白节点 4e62503a:14b01762f42:-7eea 持有满足规则的所需个体集"这没有意义。空白节点不是容器,它只是一个匿名资源。它就像一个 IRI 资源,只是它没有 IRI。
  • 如果你在your newer question找到了解决这个问题的方法,你应该考虑关闭/删除这个。

标签: java sparql rdf jena jena-rules


【解决方案1】:

在下一行中,您尝试获取主题,然后获取它的节点版本,然后获取它的个人版本。

System.out.println(st.getSubject().toString() + "****" + pModel.getRDFNode(st.getSubject().asNode()).as(Individual.class));

您正在为图表中每个三元组的主题执行此操作。 Individual 的文档说:

为了被认可为一个个体,而不是一个泛型 资源,至少一个 rdf:type 语句,引用一个已知的类, 必须存在于模型中。

您收到的错误消息,

无法将节点 4e62503a:14b01762f42:-7eea 转换为个人

表示在图表的某处,有一个三元组,其主题是一个空白节点。显然,其中一个空白节点不符合成为个人的标准。在执行as(Individual.class)之前,您需要检查节点是否可以是个人。您可以先使用 canAs(Individual.class) 进行检查。

但是,您需要注意,仅仅因为规则文件只有一个规则并不意味着推理图中的所有三元组都将由它生成。推理图中可以有更多的三元组。

更好的方法是使用 Model.listStatements 列出具有您关心的属性的语句,然后检查主题是否是 URI 资源, 如果是,则将其作为 URI 资源获取并提取其 URI:

Property p1 = model.createProperty(...)
StmtIterator stmts = model.listStatements(null,p1,null); 
while ( stmts.hasNext() ) {
  Statement stmt = stmts.next();
  RDFNode subject = stmt.getSubject();
  if ( subject.isURIResource() ) {
    System.out.println( "Subject URI is: "+ subject.asResource().getURI() );
  }
}

【讨论】:

  • 嗨,我想要的是这个特殊的独立(空白节点),因为它与我要查询的属性(对象/数据属性)相关。是的,所有的语句都在这里打印出来,但是我的代码后来只提取了这个特定的语句,它的属性是“hasPropertyP1”,它包含节点值而不是 iri。如果我已经编写了规则以直接引用个人而不是类的变量 ?x,我可以获得 iri,这很明显,但我想要所有类元素,那么如何编写 jena 规则?
  • 这个节点是指类Class1的那些个体,谓词hasPropertyP1。而不是节点,我想要它的组成部分(个人)。这我不能在 java 代码中做,因为我希望它是通用的,因此需要适当地编写规则来获取这些数据。我之前不确定,因此要求调用正确的 api,但看起来这是正确的编写规则,以便过滤器将包含包含相应类 (Class1) 个体而不是类节点本身的所有语句。我想jena和rdf的规则有一些限制,那么该怎么做呢?
  • @user3747396 空白节点没有有 IRI,这就是它们空白的原因。我不确定你试图获取空白节点的 IRI 是什么意思。我不知道您所说的“节点的成分”是什么意思。你的意思是你想要一个类的元素吗?我真的不知道你在问什么。
  • 是的,我想要满足 hasPropertyP1 的类的那些虹膜(元素)。如果我将规则( ?x rdf:type :Class1) ( ?x hasPropertyP1 :Object2) 更改为( :Individual1 :hasPropertyP1 :Object2),我可以看到个人,但如果我必须这样写,我需要为每个相应的个人写,如果这是唯一的做事方式,整个概念使用本体本身进行分类并没有多大用处,因为我想通过调整本体类而不是每个个体来调整事物。我想要:Class1 :hasPropertyP1 :Object 并获得令人满意的 Class1
  • @user3747396 那么听起来您试图回答“个人将 o 作为属性 p 的值是什么?”规则不提供答案;他们从图中生成(或删除)三元组。这就是你可以用它们做的所有事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 2013-07-09
  • 2017-02-23
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多