Reputation: 5771
This is a follow-up to my question here: MarkLogic template driven extraction and triples: dealing with array nodes
So let's say I have a number of documents structured like this:
declareUpdate();
xdmp.documentInsert(
'/test/tde.json',
{
content: {
name:'Joe Parent',
children: [
{
name: 'Bob Child'
},
{
name: 'Sue Child'
},
{
name: 'Guy Child'
}
]
}
},
{permissions : xdmp.defaultPermissions(),
collections : ['test']})
I want to define a template that would extract triples from these documents defining sibling relationships between the children. For the above example, I would want to extract the following triples (the relationship is two-way):
Bob Child sibling-of Sue Child
Bob Child sibling-of Guy Child
Sue Child sibling-of Bob Child
Sue Child sibling-of Guy Child
Guy Child sibling-of Bob Child
Guy Child sibling-of Sue Child
How can i set up my template to accomplish this?
Thanks!
Upvotes: 2
Views: 109
Reputation: 433
I don't know of a way to do that, but it seems like any "sibling-of" relationship is equivalent to two "child-of" relationships. Could you do something like this instead?
{
?x is-parent-of ?a-child .
?x is-parent-of ?b-child.
?a-child != ?b-child
}
Or if you're in a position to use inference rules, you can build a rule that defines "sibling-of" like that. Then although the template doesn't generate "sibling-of" directly, the triples are still tied to the ingested document in the same way as they would be, by virtue of the template generating the "is-parent-of" triples.
Upvotes: 1
Reputation: 437
I converted JSON to XML, wrote XSLT transformation to get XML triples. Later XML can be transformed back to JSON if needed.
XSLT transformation:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:json="http://marklogic.com/xdmp/json/basic" xmlns:sem="http://marklogic.com/semantics" exclude-result-prefixes="json">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="json:content">
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<xsl:apply-templates select="json:children"/>
</sem:triples>
</xsl:template>
<xsl:template match="json:children">
<xsl:for-each select="json:json">
<xsl:variable name="subjectName">
<xsl:value-of select="json:name/text()"/>
</xsl:variable>
<xsl:for-each select="following-sibling::* | preceding-sibling::* ">
<sem:triple>
<sem:subject>
<xsl:value-of select="$subjectName"/>
</sem:subject>
<sem:predicate>sibling-of</sem:predicate>
<sem:object><xsl:value-of select="json:name/text()"/></sem:object>
</sem:triple>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XQuery code that converts JSON to XML and makes transformation:
xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
declare namespace sem = "http://marklogic.com/semantics";
declare variable $j := '{"content": {"name": "Joe Parent","children": [{"name": "Bob Child"}, {"name": "Sue Child"}, {"name": "Guy Child"}]}}';
let $doc := json:transform-from-json($j),
$xslt := doc("myTemplates.xsl"),
$result := xdmp:xslt-eval($xslt,$doc),
$config := json:config("custom"),
$_ := map:put($config, "whitespace", "ignore"),
$_ := map:put($config, "array-element-names", ("triple")),
$_ := map:put($config, "element-namespace","http://marklogic.com/semantics")
return json:transform-to-json($result, $config)
Upvotes: 0