How do I insert a triplet into a specific XML document?
First, the key here is to recognize that there are two ways to store and manage triplets in MarkLogic.
-
driven triplets - this is where you want to use MarkLogic as "just a triple store". You load triplets with mlcp (command line loader) or sem: rdf-load () or sem: rdf-insert (). In this case, you don't want to know or care about the documents that store the triplets - you just want to download the triplets so that you can query them later using SPARQL. Therefore sem: rdf-insert () has no "insert into this document" argument.
-
inline triplets - triplets are embedded in an XML (or JSON) document. In this case, the troika is conceptually part of the document; so if you want to insert a triplet into a document (insert a triplet into a document), you should look for document processing APIs, not triples APIs.
Once you have this mental model, you can use sem: rdf-insert () if your triple is essentially "free floating", meaning it doesn't matter which document it is in. Or you can use something like xdmp: node-insert-child () if you really want to place this triplet inside an existing document at some position. (In MarkLogic 8, you can also use SPARQL Update to insert managed / free floating triplets.
However, I wanted to see if I could make the node-internet-child in a simpler and more intuitive way, i.e. without the "trick" above.
First, it is helpful to create a triple using sem: iri () and sem: triple () above, although you could create a triple in XML directly. Using sem constructors: more reliable.
Second, sem: triple () returns an object of type sem: triple, not an XML node. Therefore, you cannot pass it to xdmp: node-insert-child () directly. But there is a helper function for translating from sem: triple to XML node - sem: rdf-serialize () with the "triplexml" option.
So, you can do this:
xdmp:document-insert( "/test/test.xml", <doc><title>test</title></doc>)
then
import module namespace sem = "http://marklogic.com/semantics"
at "/MarkLogic/semantics.xqy";
xdmp:node-insert-child(
fn:doc('/test/test.xml')/doc,
sem:rdf-serialize(
sem:triple(sem:iri("Firefly"), "is-a", "TV show"),
"triplexml"
)
)
... and you get:
fn:doc('/test/test.xml')
=>
<doc>
<title>test</title>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<sem:triple>
<sem:subject>Firefly</sem:subject>
<sem:predicate datatype="http://www.w3.org/2001/XMLSchema#string">is-a</sem:predicate>
<sem:object datatype="http://www.w3.org/2001/XMLSchema#string">TV show</sem:object>
</sem:triple>
</sem:triples>
</doc>
source to share
Alex, you can insert a triplet into a document with xdmp: node-insert-child (). There is one trick: the function expects a node and the triple is not a node. It works:
xdmp:node-insert-child(
fn:doc('has-a-triple.xml')/doc,
<t>{sem:triple(sem:iri("Firefly"), "is-a", "TV show")}</t>/*
)
If you try it without the trick <t/>/*
, you will get an error:
xdmp:node-insert-child(
fn:doc('has-a-triple.xml')/doc,
sem:triple(sem:iri("Firefly"), "is-a", "TV show")
)
returns
XDMP-ARGTYPE: (err:XPTY0004) xdmp:node-insert-child(fn:doc("has-a-triple.xml")/doc,
sem:triple(sem:iri("Firefly"), "is-a", "TV show")) -- arg2 is not of type node()
source to share
While I don't think you can do this with rdf-insert, you might find it helpful to check the built-in triplets in the documentation:
The Developer's Guide MarkLogic Semantics
Ternary documents with sem: Ternary, since they are controlled by the document root of triplets in MarkLogic Server.
You can also embed triplets in XML documents and load them into MarkLogic as-is.
For example:
<?xml version="1.0" encoding="UTF-8"?> <article> <info> <title>News for April 9, 2013</title> <sem:triples xmlns:sem="http://marklogic.com/semantics> <sem:subject>http://example.org/article</sem:subject> <sem:predicate>http://example.org/mentions</sem:predicate> <sem:object>http://example.org/London</sem:object> </sem:triples> </info> </article>
Downloaded triplets are automatically indexed by a special triple index. The triple index allows you to immediately search for RDF Data for which you have the necessary privileges.
So, maybe you can try inserting a sem: triples node into the document and see if it gets indexed?
source to share