Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a triple into a specific XML document?

Tags:

marklogic

I noticed that while rdf-insert does not allow you to specify a document, only a graph.

like image 654
Alex J. Avatar asked Feb 26 '26 22:02

Alex J.


1 Answers

First, the key here is to recognize that there are two ways of storing and managing triples in MarkLogic.

  1. managed triples - this is where you want to use MarkLogic as "just a triple store". You load triples using mlcp (the command-line bulk loader) or sem:rdf-load() or sem:rdf-insert(). In this scenario, you don't want to know or care which documents the triples are stored in - you just want to load triples so you can query them later with SPARQL. That's why sem:rdf-insert() doesn't have an "insert it into this document" argument.

  2. embedded triples - triples are embedded in an XML (or JSON) document. In this scenario, the triple is conceptually part of the document; so if you want to insert a triple into a document (embed a triple in a document) you should look to the document manipulation APIs rather than the triples manipulation APIs.

Once you have that mental model, you can choose to use sem:rdf-insert() if your triple is essentially "free-floating" - i.e. it doesn't matter which document it's in. Or you can choose to use something like xdmp:node-insert-child() if you really want to place that triple inside an existing document at some position. (In MarkLogic 8 you can also use SPARQL Update to insert managed/free-floating triples.

That said, I wanted to see if I could do the node-insert-child in a simpler, more intuitive way - i.e. without the "trick" above.

First, it's good to build up the triple using sem:iri() and sem:triple() above - though you could build up the triple directly in XML. Using the sem: constructors is more robust.

Second, sem:triple() returns an object of type sem:triple, not an XML node. So you can't pass it in to xdmp:node-insert-child() directly. But there is a helper function to translate from a sem:triple into an XML node - sem:rdf-serialize(), with a "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'll 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>
like image 184
SBuxton Avatar answered Mar 03 '26 14:03

SBuxton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!