首页 > 解决方案 > 图形序列化(空白节点标签)

问题描述

我正在尝试按照URDNA2015 算法进行一些图形标准化。

如果我理解规范,空白节点应该有像 _:c14nX 这样的标签,其中 X 是一个递增计数器。

我可以生成一个带有带有这些标签的空白节点的图形,但是当将图形序列化为 NTRIPLES 时,这些图形通过执行一些编码的 NodeFmtLib#encodeBNodeLabel 运行——至少总是在结果节点前加上“B”。例如 c14n92 -> Bc14n92 或 _:c14n92 -> BX5FX3Ac14n92 由于十六进制编码。

我的序列化代码目前非常基本:

        StringWriter sw = new StringWriter();
        RDFDataMgr.write(sw, normalizedGraph, Lang.NTRIPLES);

更好地控制此序列化的建议方法是什么?

编辑:我发现一种可行的方法,但我不确定它是否是推荐的方法:

RDFWriterRegistry.register(RDFFormat.NTRIPLES_UTF8, new CustomWriterGraphRIOTFactory());

然后实现一个覆盖的类链:

最终到达覆盖 formatBNode 的地方:

public class CustomNodeFormatter extends NodeFormatterNT {
    public CustomNodeFormatter(CharSpace charSpace) {
        super(charSpace);
    }

    @Override
    public void formatBNode(AWriter w, String label) {
        w.print(label);
    }
}

标签: jena

解决方案


Jena 的作者处理图,图是一组三无序的。由于可以删除和重新添加三元组,因此即使在单线程程序中排序也不是那么容易,因为对图的更改可能会重新排序哈希表。

如果您从 JSON-LD 执行此操作 - Jena 当前使用 jsonld-java - 检查 JSON-LD 解析的顺序和标签是否一致。

如果您想尊重其他格式的语法顺序,请查看将文件解析为StreamRDF对象(-解析器输出流,-以及具有自定义 FactoryRDF(控制用于空白节点的标签)例如此时将它们设为 1,2,3)。

RDFParser.create().source(...).factory(FactoryRDF).parse(StreamRDF);

请注意,在不控制输入的情况下通过输出执行此操作时,输出的顺序可能会因运行而异,因为每个解析器运行时空白节点会获得不同的 id。


推荐阅读