Define class hierarchy in Notation 3 - class

I am trying to develop a simple Notation3 ontology file.
so far my code in the notation3 file is
#prefix my: <http://www.codeproject.com/KB/recipes/n3_notation#>.
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
my:batterycs a my:spec;
my:preferedby my:BusinessPerson, my:LoveBird, my:MusicLover, my:Travelar;
my:name "batteryCS".
rdfs:Person a rdfs:Class.
I am using dotNetRdf library to read and query the ontology file. the above code in n3 file works fine. But when I Insert
rdfs:Woman a rdfs:Class; rdfs:subClassOf :Person .
at the end of the ontology file it occurs the error Unable to resolve the QName ':Person' seems like it cant even load the ontology to the parser.
I studied the n3 syntax from http://www.w3.org/2000/10/swap/Primer.html
can somebody help me with this where I have made the mistake
thanks in advance

Your data is invalid, you need to define the empty prefix in order to be able to refer to it in a QName such as :Person
A QName (Qualified Name) is a syntactic shortcut which allows you to shorten URIs written in the form prefix:name where prefix must refer to a defined namespace prefix defined via a previous #prefix statement. The parser then simply looks up the prefix and concatenates it with the name part, so for example rdfs:Class is expanded to http://www.w3.org/2000/01/rdf-schema#Person in your example data.
If a prefix is not defined then a RDF parser is expected to throw an error.
So you need to fix your data, there are a couple of ways to do this depending on what your intent was.
You meant to put :Person in your own my: namespace
Simply replace :Person with my:Person
Note that you have also referred to rdfs:Person so your data looks somewhat inconsistent
You meant to defined an empty namespace
Simply add the following #prefix definition:
#prefix : <http://example.org/namespace#> .
Where the URI is the desired namespace URI
Aside
What version of dotNetRDF are you using? And is the error message you quote the complete error message?
More recent versions of dotNetRDF are supposed to give more informative error messages that should have told you that you were likely missing a prefix declaration

Related

How to isolate a list of URIs in a RDF file using CONSTRUCT or DESCRIBE in SPARQL?

I'm trying to get only a list of URIs in RDF instead of a list of triples:
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
DESCRIBE ?product
WHERE
{
?product rdfs:subClassOf gr:ProductOrService .
}
Using SELECT, instead of DESCRIBE I receive only the subject (which I want), but not as an RDF but like a SPARQL Result with binds, vars, etc.
Using CONSTRUCT, I can't specify only the ?product, as above, so the closest I can get is:
PREFIX gr: <http://purl.org/goodrelations/v1#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
CONSTRUCT
WHERE
{
?product rdfs:subClassOf gr:ProductOrService .
}
Which returns an RDF with triples of different products, but the same properties and objects.
It looks like you should read over the SPARQL specification, which tells you that this is exactly as expected. To get the single column you wish, you must use SELECT.
SPARQL has four query forms. These query forms use the solutions from pattern matching to form result sets or RDF graphs. The query forms are:
SELECT
Returns all, or a subset of, the variables bound in a query pattern match.
CONSTRUCT
Returns an RDF graph constructed by substituting variables in a set of triple templates.
ASK
Returns a boolean indicating whether a query pattern matches or not.
DESCRIBE
Returns an RDF graph that describes the resources found.
I found a solution. I've used SELECT, but instead of binds and vars, as output received a "Comma-Separated Values (with fields in N-Triples syntax)" CSV file:
<http://www.productontology.org/id/Real_estate>
<http://www.productontology.org/id/Automobile>
<http://www.productontology.org/id/Auction>
<http://www.productontology.org/id/Video_game>
<http://www.productontology.org/id/Campsite>
<http://www.productontology.org/id/Car>
<http://www.productontology.org/id/Audiobook>
<http://www.productontology.org/id/Browser_game>
...
Representing the result of a SPARQL SELECT query as an RDF List is a tooling issue - it is not something that can be solved in SPARQL in general.
Some SPARQL tools may have ways to support rendering the query result as an RDF list. But it's not something you can fix by just formulating your query differently, you'll need to use a tool to (programmatically) format the result.
In Java, using Eclipse RDF4J, you can do it as follows (untested so you may need to tweak it to work properly, but it should give you a general idea):
String query = "SELECT ?product WHERE { ?product rdfs:subClassOf gr:ProductOrService . }";
// do the query on repo and convert to a Java list of URI objects
List<URI> results = Repositories.tupleQuery(
repo,
query,
r -> QueryResults.stream(r).map(bs -> (URI)bs.getValue("product")).collect(Collectors.toList()
);
// create a resource (bnode or URI) for the start of the rdf:List
Resource head = SimpleValueFactory.getInstance().createBNode();
// convert the Java list of results to an rdf:list and add it
// to a newly-created RDF Model
Model m = RDFCollections.asRDF(results, head, new LinkedHashModel());
Once you have your result as an RDF model you can use any of the existing RDF4J APIs to write it to file or to store it in a triplestore.
Now, I am not claiming that any of this is a good idea - I have never seen a use case for something like this. But this is how I would do it if it were necessary.

How to make Custom Rule set in Graphdb

I am trying to make customs rules in Graphdb. I have a Person ontology which has classes "Parent" and "Child", and object property "hasChild" and "hasGrandChild".
There are three nodes with relationship like this:
:Ali :hasChild :Aslam
:Aslam :hasChild :Ahmed
Now I want to infer that ":Ali :hasGrandChild :Ahmed" in Graphdb. Builtin ruleset like owl horst optimized does not work.
I tried using .pie file for making custom rules but new rules are not working
GraphDB gives you the flexibility to develop your own rules if you want to express semantics not part of the OWL or RDFS standards. In this example, you try to define that the property hasGranChild is a chain of two hasChild properties. This is possible with OWL property chain axiom.
My suggestion is to use the standard OWL semantics part of OWL 2 RL and OWL 2 QL rulesets in GraphDB. Here is an example:
#prefix : <http://www.example.org/> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
:hasParent a owl:ObjectProperty .
:hasGrandChild owl:propertyChainAxiom
( :hasChild :hasChild ) .
:Ahmed :hasChild :Ali .
:Ali :hasParent :Aslam .
Please do not forget to change the default ruleset to OWL 2 RL or OWL 2 QL during the repository creation.
I created a ruleset file called “CustomRule.pie”. It has three main parts “Prefices”, “Axioms”, and “Rules”.
In Prefices, I inserted our ontology Prefix like:
Person :http://www.semanticweb.org/hamza/ontologies/2017/6/Person.owl#
Then in Axioms, we have to write all the triples Subject, Predicate, Object that we have inserted in our ontology. Like:
<'Person:Ahmed'> <'Person:hasChild'> <'Person:Ali'>
<'Person:Ali'> <'Person:hasChild'> <'Person:Aslam'>
//Ingore commas
Finally, in Rules section, we can write entailment rules. It checks all the axioms available in the Axioms section to implement rules. Like
Id: custom
a <'Person:hasChild'> b
b <'Person:hasChild'> c
------------------------------------
a <'Person:hasGrandChild'> c

Xtext assign object in xtext file

Trying to make a meta model for Mongoose and MondoDb, using metamodeling concepts, eclipse and xtext.
I am trying to assign object that i created in my test.mydsl file to another object in the same file, but i get error in my test.mydsl file.
I am trying to assign created Schema(sc1) object to Collection(col) object, but currently getting an error
error message
the feature 'validate' of
'paket.impl.NCollectionImpl#67d76e14{platform:/resource/test/classes/test.mydsl#//#collections.0}'
contains an unresolved proxy
'paket.impl.SchemaImpl#361d8284{platform:/resource/test/classes/test.mydsl#|0}'
my grammar for Schema and Collection
Schema returns Schema:
{Schema}
('Schema' '<' Name=EString) '>'
'{'
(schemaExpression+=Expression ( "," schemaExpression+=Expression)*)?
(verificationDocumentElement+=VerDocElement ( "," verificationDocumentElement+=VerDocElement)*)?
'}';
NCollection returns NCollection:
{NCollection}
('Collection' '<' Name=EString) ',' (validate=[Schema|EString])? '>'
'{'
(document+=Document ( "," document+=Document)*)?
'}';
my test.mydsl
Database<db1>{
Schema<sc1>{
var ja=lp
ime:{
type:String,
min:123.0
}
}
Collection<col, sc1>
{
}
}
I tried all, but unsuccessful.
Any ideas what to do?
Thanks
EDIT:
Maybe I was not clear enough. The major problem is with "validate" attribute in NCollection rule.
When I create my Schema object(sc1 in test.mydsl) and then try to pass it to Collection(col in test.mydsl) as a "sc1", the "validate" attribute cannot accept it like string, and I don't know how to pass it like Schema object.
I hope this explanation helps.
Please try to use name=EStringinstead of Name=EString as Xtext imposes a special default semantics for the attribute name. Also I recommend to look into the documentation.
The code
validate=[Schema|EString]
says: I want a schema reference via a String, i.e. "sc1" instead of the name. Xtext doesn't know how to convert a string into a reference. Use this instead:
validate=[Schema]
which is short for
validate=[Schema|ID]
That will use the name of the Schema as reference. Note that you have to write
('Schema' '<' name=EString) '>'
i.e. lower case name to make it work. Xtext has special handling for properties called name.

RDF document metadata

I have a software that generates an RDF representation of certain dataset. I want to add to the generated data also some metadata describing not specific data contained in the data set but the document itself - i.e., when the document was created, by which software, which version, etc. The schema.org properties provide the necessary relationships, but I can not figure out the proper place to attach it. Is there some standard way of saying "this is the metadata about the document itself" in RDF? I use Turtle serialization for RDF but generic answer working with any serialization would be preferable.
There is not a standard place to do this. A RDF graph is just a collection of triples; it's not identified by an IRI or anything like that. (However, in SPARQL datasets, you could post some metadata about a named graph by using the name of the graph as the subject in a triple. That would just be a convention, though. It's not "official" in any sense.)
In the RDF serializations of OWL ontologies, there can be an ontology element (i.e., a resource with the type owl:Ontology), and that can be used to associate some metadata with the ontology. You'd probably want to adopt an approach like that. That is, you'd establish a convention with something like
#prefix ex: <...>
[] a ex:DatasetRepresentation ;
ex:created "..." ;
ex:representationOf <...> .
#... rest of generated content ...
I am not that familiar with Schema.org, but both DCat and Doublin Core provide means to do so.
In Doublin Core there is the identifier Data property. An example:
PREFIX : <http://my.domain/meta-data#>
PREFIX dcterms: <http://purl.org/dc/terms/>
:1 a dcterms:BibliographicResource ;
dcterms:identifier <http://my.domain/my-document> .
A similar record but now using DCat and the landingPage data property:
PREFIX : <http://my.domain/meta-data#>
PREFIX dcat: <http://www.w3.org/ns/dcat#>
:1 a dcat:Resource ;
dcat:landingPage <http://my.domain/my-document> .

Why is this xmlns attribute messing up my xpath query?

I'm parsing a simple jhove output using LibXML. However, I don't get the values I expect. Here's the code:
use feature "say";
use XML::LibXML;
my $PRSR = XML::LibXML->new();
my $xs=<DATA>;
say $xs;
my $t1 = $PRSR->load_xml(string => $xs);
say "1:" . $t1->findvalue('//date');
$xs=<DATA>;
say $xs;
$t1 = $PRSR->load_xml(string => $xs);
say "2:" . $t1->findvalue('//date');
__DATA__
<jhove xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://hul.harvard.edu/ois/xml/ns/jhove" xsi:schemaLocation="http://hul.harvard.edu/ois/xml/ns/jhove http://hul.harvard.edu/ois/xml/xsd/jhove/1.3/jhove.xsd" name="Jhove" release="1.0 (beta 3)" date="2005-02-04"><date>2006-10-06T09:11:34+02:00</date></jhove>
<jhove><date>2006-10-06T09:11:34+02:00</date></jhove>
As you can see, the line "1:" is returning an empty string, while "2:" is returning the expected date. What is in the jhove-root-element that keeps the xpath query from working properly? I even tried in XML-Spy and there it works, even with the full header.
Edit: When I remove the xmlns-attribute from the root element, the xpath query works. But how is that possible?
The XML::LibXML::Node documentation specifically mentions this issue and how to deal with it...
NOTE ON NAMESPACES AND XPATH:
A common mistake about XPath is to assume that node tests consisting of an element name with no prefix match elements in the default namespace. This assumption is wrong - by XPath specification, such node tests can only match elements that are in no (i.e. null) namespace.
So, for example, one cannot match the root element of an XHTML document with $node->find('/html') since '/html' would only match if the root element <html> had no namespace, but all XHTML elements belong to the namespace http://www.w3.org/1999/xhtml. (Note that xmlns="..." namespace declarations can also be specified in a DTD, which makes the situation even worse, since the XML document looks as if there was no default namespace).
There are several possible ways to deal with namespaces in XPath:
The recommended way is to use the XML::LibXML::XPathContext module to define an explicit context for XPath evaluation, in which a document independent prefix-to-namespace mapping can be defined. For example:
my $xpc = XML::LibXML::XPathContext->new;
$xpc->registerNs('x', 'http://www.w3.org/1999/xhtml');
$xpc->find('/x:html',$node);
Another possibility is to use prefixes declared in the queried document (if known). If the document declares a prefix for the namespace in question (and the context node is in the scope of the declaration), XML::LibXML allows you to use the prefix in the XPath expression, e.g.:
$node->find('/x:html');
I found another solution. Simply using this
say "1:" . $t1->findvalue('//*[local-name()="date"]');
will also find the value and save the hassle of declaring namespaces in an XPathContext. But apart from that, tobyinks answer is the correct one.