繁体   English   中英

JENA:基于String对象创建单个Statement

[英]JENA : Create a single Statement based on a String object

我必须解析N-TRIPLE内容,并对给定类型的每个文字进行修改。

例如,我必须修改每个WKTLiteral以使其使用引用。 三元组,例如:

"POINT (0.0 0.0)"^^<http://www.opengis.net/ont/geosparql#wktLiteral>

必须成为:

"<http://www.opengis.net/def/crs/EPSG/0/4326> POINT (0.0 0.0)"^^<http://www.opengis.net/ont/geosparql#wktLiteral>

我将每三行逐行放入String对象,并希望从此String创建Jena语句。 我的目的是使用Jena解析器来避免一些肮脏的String操作,例如split容易出错。

目前,我发现这样做的唯一方法是:

String line = "%a triple is here%";
//Create an empty model
final Model model = ModelFactory.createDefaultModel();
//Parse and store the RDF triple in the model
RDFDataMgr.read(model, new ByteArrayInputStream(line.getBytes(StandardCharsets.UTF_8)), Lang.NTRIPLES);
//Get all the statements - only 1 if any
final StmtIterator listStatements = model.listStatements();
//Got my statement
final Statement statement = listStatements.next();

我也尝试使用RDFReader,但不知道要使用RDFOutputStream ...为了只从String自动创建一个Statement对象,我必须创建一个Model,使用Reader和Iterator。 在我看来,这似乎是过高的(我切断了大部分测试,例如测试实际上存在下一条语句……)。

您知道实现这一目标的简单方法吗?

亚瑟。

我不知道您是否会找到比您真正拥有的更好的方法,只是您可能应该读取文件的块而不是每一行。 如果读入文件的块,则可以使用简单的构造SPARQL查询来转换整个块。 这将提供一个新模型,您可以将该模型的N-TRIPLE序列化附加到您的输出文件中(或将其插入到新图形中,等等)。 假设您有以下数据:

<urn:ex:a> <urn:ex:p> <urn:ex:b>.
<urn:ex:c> <urn:ex:q> "POINT (0.0 0.0)"^^<http://www.opengis.net/ont/geosparql#wktLiteral>.

然后,像这样的查询将产生以下更新的模型:

construct { ?s ?p ?oo }
where {

  #-- constant values pulled out for readability; this
  #-- is optional, of course.
  values (?dt ?prefix) {
    (<http://www.opengis.net/ont/geosparql#wktLiteral>
    "<http://www.opengis.net/def/crs/EPSG/0/4326> ") 
  }

  #-- grab each triple, and bind ?oo to ?o if it doesn't 
  #-- need to be updated, or to a new literal, if it does.
  ?s ?p ?o .
  bind( if( isLiteral(?o) && datatype(?o) = ?dt,
            strdt( concat(?prefix,str(?o)), ?dt ),
            ?o )
        as ?oo )
}
<urn:ex:a> <urn:ex:p> <urn:ex:b> .
<urn:ex:c> <urn:ex:q> "<http://www.opengis.net/def/crs/EPSG/0/4326> POINT (0.0 0.0)"^^<http://www.opengis.net/ont/geosparql#wktLiteral> .

如果要将整个数据集加载到TDB实例中,则可以使用此方法的某些变体相对容易地转换整个数据集,然后将最终数据转储到新文件中。

您会发现使用更有效。 StreamRDF实例在遇到它们时会发送三倍 然后,您可以根据需要进行重写。

流使用耶拿的SPI级别-节点,三元组和四元组,而不是语句,资源等-虽然缺少一些好处,但对于这样的任务,它们是理想的。

鉴于您已经写了什么,我怀疑要写出固定的N-Triples是您想要的吗? 这是一个可以做到这一点的例子。 它所做的就是1)创建一个流以输出三元组,2)创建一个等待三元组的流,更正对象(如果需要),然后写入结果,然后3)启动整个解析过程:

final String wkt = "http://www.opengis.net/ont/geosparql#wktLiteral";

// Stream result to stdout
final StreamRDF outputHandler = StreamRDFLib.writer(System.out);

StreamRDF inputHandler = new StreamRDFBase() {
    @Override
    public void triple(Triple triple) { // Got a triple
        Node object = triple.getObject();

        Node transformed;
        // if object is literal and has wkt type
        if (object.isLiteral() &&
                wkt.equals(object.getLiteralDatatypeURI())) {
            // Make a new node, suitably modified
            transformed = NodeFactory.createLiteral(
                    "<http://www.opengis.net/def/crs/EPSG/0/4326> " 
                            + object.getLiteralLexicalForm(), 
                    object.getLiteralDatatype());
        } else { // Do nothing
            transformed = object;
        }

        // Write out with corrected object
        outputHandler.triple(
                Triple.create( triple.getSubject(), triple.getPredicate(),
                        transformed
                        ));
    }
};

// Parse 
RDFDataMgr.parse(inputHandler, RDFDataMgr.open("file"));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM