Replacing blank node IDs

52 views
Skip to first unread message

simon

unread,
Mar 18, 2021, 8:54:32 PM3/18/21
to rdf4j...@googlegroups.com
I've Triples extracted from the web like:

_:na43d612388514fcfaaa74771e40a879cxb0
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://schema.org/Product> .
_:na43d612388514fcfaaa74771e40a879cxb0 <http://schema.org/brand>
_:na43d612388514fcfaaa74771e40a879cxb2 .
_:na43d612388514fcfaaa74771e40a879cxb0 <http://schema.org/mpn> "925872" .
_:na43d612388514fcfaaa74771e40a879cxb0 <http://schema.org/name>
"Executive Anvil" .
...

but would like to replace the blank node IDs with non-blank IDs that
reflect the URI where the data came from. I've loaded the data in a
RDF4J Model successfully but don't know if what I want to do is
possible or how to proceed from there.

Thanking you in advance for your help and suggestions, Simon.

Jeen Broekstra

unread,
Mar 18, 2021, 11:26:16 PM3/18/21
to RDF4J Users
Off the top of my head a simple way to do this for a Model is something like this:

Model model = ... // your model with blank nodes
Model converted = model.stream.map(st -> convert(st)).collect(ModelCollector.toModel());

Statement convert(Statement st) {
        var subject = st.getSubject();
        var object = st.getObject();
        if (!(subject.isBNode() || object.isBNode())) {            
            return st;
        }

        IRI newSubject = subject.isBNode() ? Values.iri("http://example.org/", subject.stringValue()) : (IRI) subject;
        Value newObject = object.isBNode() ? Values.iri("http://example.org/", object.stringValue()) : object;

        return Values.statement(newSubject, st.getPredicate(), newObject, st.getContext());
}


Of course, what's also possible is to do the conversion while parsing (so before you even have created a Model object for it), something like this:
       
        RDFParser parser = Rio.createParser(RDFFormat.TURTLE);
        parser.getParserConfig().set(BasicParserSettings.SKOLEMIZE_ORIGIN, "http://example.org/");

        Model model = new TreeModel();
        parser.setRDFHandler(new StatementCollector(model));
        parser.parse(input);

        model.forEach(System.out::println); // will print out the model to show all bnodes converted to IRIs


Cheers,

Jeen

simon t

unread,
Mar 19, 2021, 8:42:20 PM3/19/21
to RDF4J Users
I wanted more control of the IDs than SKOLEMIZE_ORIGIN provided so went something closer to the convert() approach, streaming and map-ing worked great.

Thanks for saving me some time figuring this out, Simon
Reply all
Reply to author
Forward
0 new messages