I'm trying to retrieve all elements of a rdf:Seq with SPARQL. The RDF structure is as follows. A subproject with a rdf:Seq of timeclaims and the individual timeclaim information. The list of timeclaims for a subproject can be of any length:
<rdf:Description rdf:about="http://www.example.com/resource/subproject/2017-nieuw-1">
<rdf:type rdf:resource="http://www.example.com/ontologie/example/Subproject"/>
<rdfs:label>Subproject label</rdfs:label>
<pbl:subproject_timeclaims rdf:resource="http://www.example.com/resource/list/5853abbfdcc97"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.example.com/resource/list/5853abbfdcc97">
<rdf:type rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq"/>
<rdf:_1 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd6aa4"/>
<rdf:_7 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd957b"/>
<rdf:_6 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd8e68"/>
<rdf:_14 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfdc541"/>
<rdf:_5 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd879f"/>
<rdf:_2 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd71db"/>
<rdf:_3 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd78be"/>
<rdf:_4 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd7f92"/>
<rdf:_8 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfd9c4c"/>
<rdf:_9 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfda31c"/>
<rdf:_10 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfdaa08"/>
<rdf:_11 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfdb0e6"/>
<rdf:_12 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfdb7bd"/>
<rdf:_13 rdf:resource="http://www.example.com/resource/timeclaim/5853abbfdbe7f"/>
</rdf:Description>
<rdf:Description rdf:about="http://www.example.com/resource/timeclaim/5853abbfdc541">
<rdf:type rdf:resource="http://www.example.com/ontologie/example/Timeclaim"/>
<pbl:timeclaim_description>Description</pbl:timeclaim_description>
<pbl:timeclaim_hours>25</pbl:timeclaim_hours>
<pbl:timeclaim_employee
rdf:resource="http://www.example.com/resource/employee/2222333334444"/>
</rdf:Description>
Starting from the timeclaims I'm trying to retrieve the information of the subproject above (and filter on it). But the query is taking forever. Eventually the data is returned but I have the feeling it could be quicker.
SELECT *
WHERE {
?tc_item a :Timeclaim .
?tc_list ?p ?tc_item .
?subproject pbl:subproject_timeclaims ?tc_list
}
Could you point out any mistakes in the SPARQL query and better ways of doing this? Or maybe the RDF structure could be improved? The numbering in this case is not really relevant but the same list structure with rdf:Seq is present in more places in the database (and the order is important in those cases).
I am writing a SPARQL query to get name and expertise from 2 rdf files. Using rdflib graph() I can parse and query one rdf files at a time but I could not get the join ideas here. How can I do that? How can I parse two rdf files and make a join SPARQL query for example UNION in python client? please share your idea's. Thank you.
name.rdf
<rdf:RDF
xmlns:researche="http://example.com/researche#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="http://example.app.web/researche#researcher1">
<researche:name>John Snow</researche:name>
<researche:hasExpertise rdf:resource="http://example.com/researche#expertise1"/>
<researche:hasExpertise rdf:resource="http://example.com/researche#expertise3"/>
</rdf:Description>
</rdf:RDF>
expertise.rdf
<rdf:RDF
xmlns:researche="http://example.com/researche#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="http://example.com/researche#expertise1">
<researche:name>Web engineering</researche:name>
</rdf:Description>
<rdf:Description rdf:about="http://example.com/researche#expertise2">
<researche:name>DevOps</researchee:name>
</rdf:Description>
</rdf:RDF>
Here is my query.py file..
g.parse("name.rdf")
g2.parse("expertise.rdf")
qres = g.query(
"""SELECT DISTINCT ?name ?expertise
WHERE {
?a researche:name ?name .
?a researche:hasExpertise ?expertise .
}""")
N:B: the query.py is incomplete.
I have following triples :
<?xml version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<sem:triple>
<sem:subject>item1</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object>20</sem:object>
</sem:triple>
</sem:triples>
<?xml version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<sem:triple>
<sem:subject>item2</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object>5</sem:object>
</sem:triple>
</sem:triples>`
This is the SPARQL query I am using to calculate sum of these quantities:
select (SUM(?p) as ?p) where { ?s <hasQty> ?p}
And the result I get is this -> "0"^^xs:integer instead of 25.
Can you please suggest what is wrong in this.
Marklogic is a very powerful and versatile tool. Having said that, the way it handles RDF & SPARQL is at least a little non-standard in my opinion.
In the future, you could probably read this: https://docs.marklogic.com/sem:rdf-serialize to learn how to convert MarkLogic's native representation of triples into standard RDF.
Now I'm not an XML expert, but I don't think your triples block is valid XML. If it were, you could write an XSLT transformation to turn it into RDF XML.
I did a little manual tidying to get well-formed XML, mainly for illustration purposes:
<?xml version="1.0" encoding="UTF-8"?>
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<sem:triple>
<sem:subject>item1</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object>20</sem:object>
</sem:triple>
<sem:triple>
<sem:subject>item2</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object>5</sem:object>
</sem:triple>
</sem:triples>
As RDF/XML, that might look something like
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns="http://wanna.be/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about="http://wanna.be/item1">
<hasQty>20</hasQty>
</rdf:Description>
<rdf:Description rdf:about="http://wanna.be/item2">
<hasQty>5</hasQty>
</rdf:Description>
</rdf:RDF>
I created a default namespace of http://wanna.be/, and you can use the default abbreviation to say :hasQty instead of http://wanna.be/hasQty It's a little unusual to use a bare word like <hasQty> as a URI for a term in SPARQL query.
Therefore, to get the sum of quantities, cast each quantity string to an int and then sum:
PREFIX : <http://wanna.be/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select (sum(xsd:int(?o)) as ?oSum) where {?s :hasQty ?o}
I think Mark is on the right track with his casting of string to int. But you can create triples with typed values too. Simplest way is either using SPARQL Update, or code like the following:
xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics"
at "/MarkLogic/semantics.xqy";
sem:rdf-insert((
sem:triple(sem:iri("item1"), sem:iri("hasQty"), 20),
sem:triple(sem:iri("item2"), sem:iri("hasQty"), 5)
))
If you run above from Query Console, and Explore the database after that, you'll notice it created an XML document that looks like this:
<sem:triples xmlns:sem="http://marklogic.com/semantics">
<sem:triple>
<sem:subject>item1</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object datatype="http://www.w3.org/2001/XMLSchema#integer">20</sem:object>
</sem:triple>
<sem:triple>
<sem:subject>item2</sem:subject>
<sem:predicate>hasQty</sem:predicate>
<sem:object datatype="http://www.w3.org/2001/XMLSchema#integer">5</sem:object>
</sem:triple>
</sem:triples>
Note the datatype attribute on the sem:object elements. With that datatype attribute in place, your original SPARQL statement works just fine.
By the way, MarkLogic saves triples by default in XML documents containing each about a 100 of them, just for optimal storage. Saving each triple separately is okay, but takes more space. And you can also embed sem:triple elements within other XML documents, those get recognized too. This blog article might interest you, it gives some more background on triples in MarkLogic:
http://developer.marklogic.com/blog/managed-vs-unmanaged-triples
HTH!
I want to get an object that is a resource (see "hasAgentWithRole" predicate below).
The document (simplified to illustrate my problem):
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ns0="http://purl.org/dc/terms/"
xmlns:ns1="http://tw.rpi.edu/schema/">
<rdf:Description rdf:about="http://abstractsearch.agu.org/meetings/2014/FM/S54A-06">
<ns0:identifier>ID</ns0:identifier>
<ns1:hasAgentWithRole rdf:resource="http://abstractsearch.agu.org/meetings/2014/FM/S54A-06/author1"/>
</rdf:Description>
</rdf:RDF>
The query:
PREFIX ns1: <http://tw.rpi.edu/schema/>
SELECT ?author_uri
WHERE
{ <http://abstractsearch.agu.org/meetings/2014/FM/S54A-06> ns1:hasAgentWithRole ?author_uri}
I want to get the resource value contained within the hasAgentWithRole predicate: http://abstractsearch.agu.org/meetings/2014/FM/S54A-06/author1
However, my current query using arq throws an IRIImplException:
Does the error really occur with the current data and query shown in the question? Just from the exception, you can see that in the resultset there is some malformed IRI file:///C:/Users/abartoli/... I guess it's not a resource in your data. That means you have somewhere resources with a relative IRI which resolve to the document if no base IRI is given.
I have 3 ontology files where the first imports the second and the second imports the third:
The first ontology imports the second one:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.example.com/user/rainer/ontologies/2016/1/usecase_individuals#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:uc="http://www.example.com/user/rainer/ontologies/2016/1/usecase#">
<owl:Ontology rdf:about="http://www.example.com/user/rainer/ontologies/2016/1/usecase_individuals">
<owl:imports rdf:resource="http://www.example.com/user/rainer/ontologies/2016/1/usecase"/>
</owl:Ontology>
....
The second ontology imports the thrid one:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.example.com/user/rainer/ontologies/2016/1/usecase#"
xml:base="http://www.example.com/user/rainer/ontologies/2016/1/usecase"
xmlns:fgcm="http://www.example.com/user/rainer/ontologies/2016/1/fgcm#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:uc="http://www.example.com/user/rainer/ontologies/2016/1/usecase#">
<owl:Ontology rdf:about="http://www.example.com/user/rainer/ontologies/2016/1/usecase">
<owl:imports rdf:resource="http://www.boeing.com/user/rainer/ontologies/2016/1/fgcm"/>
</owl:Ontology>
....
And the third ontology (created in Protégé) asserts an individual:
<?xml version="1.0"?>
<rdf:RDF xmlns="http://www.boeing.com/user/rainer/ontologies/2016/1/fgcm#"
...
<owl:NamedIndividual rdf:about="http://www.boeing.com/user/rainer/ontologies/2016/1/fgcm#admin">
<rdf:type rdf:resource="http://www.boeing.com/user/rainer/ontologies/2016/1/fgcm#User"/>
<userName>admin</userName>
</owl:NamedIndividual>
...
When I open the first ontology in Protégé and execute the SPARQL query
PREFIX fgcm: <http://www.example.com/user/rainer/ontologies/2016/1/fgcm#>
SELECT ?subject ?name WHERE { ?subject fgcm:userName ?name}
it find the individual in the third ontology without a problem. When I run the same SPARQL query from code in Jena I don't get that individual. The query is run against an OntModel that was created with the default settings.
I know that Jena is able to load and import the ontologies because I can access classes and properties from the imported ontologies, both in SPARQL queries and directly using the Jena API. My problem appears to be limited to the individuals that are asserted in the imported ontology.
I have searched for settings (when loading the ontology such as the different OntModelSpecs or when creating/ running the query) that might change this behavior but haven't found any solutions.
It turned out that I was mistaken about Jena successfully loading the imported ontologies. (Not getting an error does not imply that the ontology that should be imported was actually found).
The SPARQL queries returned the expected result after using an OntDocumentManager and telling it where to find the ontology files that needed to be imported. This is the code snipped that worked for me:
OntDocumentManager mgr = new OntDocumentManager ();
mgr.addAltEntry("http://www.boeing.com/user/rainer/ontologies/2016/1/usecase", "file:C:\\Dev\\luna_workspace\\fgcm_translate\\usecase.owl");
mgr.addAltEntry("http://www.boeing.com/user/rainer/ontologies/2016/1/fgcm", "file:C:\\Dev\\luna_workspace\\fgcm_translate\\fgcm.owl");
OntModelSpec spec = new OntModelSpec ( OntModelSpec .OWL_DL_MEM_TRANS_INF);
spec.setDocumentManager(mgr);
OntModel model = ModelFactory.createOntologyModel(spec);
I hope this helps someone if they run into a similar problem.