Reputation: 100
Suppose I have two xml documents : Document 1:
<item>
<item_id> 001 </item_id>
<color>blue</color>
</item>
Document 2:
<item>
<item_ref_id>abc</item_ref_id>
<color>blue</color>
</item>
Now for inferencing, I will define a triple as:
<item_ref_id> <http://www.w3.org/2002/07/owl#sameAs> <item_id>
If I write a SPARQL query for fetching document2 with <item_id>
= abc, it should work.
Is this possible via inferencing, how can we do this kind of stuff through MarkLogic.
What all triples are needed to achieve this?
Updating the approach which i used as:
import module namespace sem = "http://marklogic.com/semantics" at
"/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";
for $doc in sem:query-results-serialize(sem:sparql( "SELECT ?s WHERE
{?s <http://www.w3.org/2002/07/owl#sameAs>
<productId>}"),"xml")//s:uri/text()
return cts:element-value-query(xs:QName($doc), '001')
The result which i get from this is:
cts:element-value-query(fn:QName("","id"), "001", ("lang=en"), 1)
cts:element-value-query(fn:QName("","productId"), "001", ("lang=en"), 1)
I have few questions regarding this: 1. Is my approach correct for solving this scenario which i have mentioned above ? 2. I am not able to use the result of sparql query and expand the query for searching the document, can you please update what i am doing wrong in this?
Upvotes: 0
Views: 129
Reputation: 20414
However, you can also leverage the sameAs triple in MarkLogic document search. While processing a search call, you could identify searches based on item_id
. You could then expand item_id
using values returned from the SPARQL call alike:
select * { ?s <http://www.w3.org/2002/07/owl#sameAs> <item_id> }
And then run the expanded search query.
-- addition --
The code you shared in your updated question is almost there, you have successfully extrapolated from productId to id. You only need to wrap the element queries into an and-query, and pass it to cts:search. Something like:
import module namespace sem = "http://marklogic.com/semantics" at
"/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";
let $qnames :=
for $id in sem:query-results-serialize(sem:sparql( "SELECT ?s WHERE
{?s <http://www.w3.org/2002/07/owl#sameAs
<item_id>}"),"xml")//s:uri/text()
return xs:QName($id)
return cts:search(collection(), cts:element-value-query($qnames, '001'))
HTH!
Upvotes: 2
Reputation: 100
@grtjn
I have got the solution for that fix, which resolves query to search for both id's, please check this:
Document1:
<item>
<item_id> 001 </item_id>
<color>blue</color>
</item>
Document2:
<item>
<item_ref_id>abc</item_ref_id>
<color>blue</color>
</item>
Triple:
<sem:triple>
<sem:subject>item_ref_id</sem:subject>
<sem:predicate>http://www.w3.org/2002/07/owl#sameAs</sem:predicate>
<sem:object>item_id</sem:object>
</sem:triple>
With this structure above, i run the following query (modified from the solution), and it resolves the document for both id's with item_id:
import module namespace sem = "http://marklogic.com/semantics"
at "/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";
for $id in sem:query-results-serialize(
sem:sparql( "SELECT ?s WHERE {?s <http://www.w3.org/2002/07/owl#sameAs> <item_id>}"),"xml")//s:uri/text()
return cts:search(collection(),cts:and-query((
cts:element-value-query(xs:QName($id), '001'))
))
It works if i pass 'abc' too for the search.
Thanks for the idea of how to use this, it helped me resolve this problem.
Upvotes: 0
Reputation: 100
I have added relationship for the above mentioned scenario in this way:
(item1 uri)---> has unique --> id ---> same as <--- productid <---- has unique <--- (item2 uri)
item_id ---> (hasValue-def) ---> 001
item_ref_id---> (hasValue-def) ----> abc
After adding the following triples i could search the item using item_id for both the items, using inferencing as:
import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy";
declare namespace s = "http://www.w3.org/2005/sparql-results#";
for $doc in sem:query-results-serialize(
sem:sparql("SELECT * WHERE {?s <has-unique-key as#>/<https://www.w3.org/TR/2002/WD-owl-ref-20021112/#hasValue-def>/<http://www.w3.org/2002/07/owl#sameAs>* <001>}"), "xml")//s:uri/text()
return fn:doc($doc)
Upvotes: 0
Reputation: 20414
You can only inference over RDF data, so you would have to convert the XML structure to triples. You could then define a rule like this:
rule "item_ref_id" construct {
?s <item_id> ?o
} {
?s <item_ref_id> ?o
}
And after that you only need to select the rule when running SPARQL to make use of it.
HTH!
Upvotes: 1