I cannot access an object property - java

I'm using Java and Jena API.
I have a class Marriage which have 3 Object Properties called "hasHusband", "Haswife" and "dateOfMarriage". The first two are associated with a class Person which has the datatypeproperties like hasFirstName, hasLastName, dateOfBirth....
I'd like to access the objects properties "Haswife" and "hasHusband" and then the wife's first name and the husband's first name.
Here is how that is represented in my rdf file:
(...)
<j.0:FAMmariage rdf:about=http://www.fam.com/FAM#BrunoCatherine>
<j.0:FAMaDateMariage>25/07/2011</j.0:FAMaDateMariage>
<j.0:FAMhasWife>
<rdf:Description rdf:about="http://www.fam.com/FAM#Catherine20/03/1982">
<j.0:FAMDateOfBirth>20/03/1980</j.0:FAMDateOfBirth>
<j.0:FAMHasName>Gomez</j.0:FAMHasName>
<j.0:FAMHasFirstName>Catherine</j.0:FAMHasFirstName>
</rdf:Description>
</j.0:FAMHasWife>
<j.0:FAMHusband>
<rdf:Description rdf:about="http://www.fam.com/FAM# Bruno15/06/1980 ">
<j.0:FAMaDateOfBirth>15/06/1980 </j.0:FAMDateOfBirth>
<j.0:FAMHasName>Jeandet </j.0:FAMHasName>
<j.0:FAMHasFirstName>Bruno</j.0:FAMHasFirstName>
</rdf:Description>
</j.0:FAMHusband>
</j.0:FAMmariage>
(...)
I tried like this but it still does not works:
StmtIterator iter = onto.model.listStatements();
while (iter.hasNext()) {
Statement stmt = iter.nextStatement();
Resource subject = stmt.getSubject();
Property predicate = stmt.getPredicate();
RDFNode object = stmt.getObject();
if (predicate.equals(onto.hasWife))
{
System.out.print(" " + object.toString() + " ");
}
}
Can you please tell me what's wrong?
Thanks
EDITED
More useful details:
(...)
person = model.createClass(uriBase+"person");
person.addSubClass(man);
person.addSubClass(woman);
marriage = model.createClass(uriBase+"marriage");
(...)
hasHusband = model.createObjectProperty(uriBase+"hasHusband");
hasHusband.setDomain(marriage);
hasHusband.setRange(man);
hasWife = model.createObjectProperty(uriBase+"hasWife");
hasWife.setDomain(marriage);
hasWife.setRange(woman);
hasFirstName = model.createDatatypeProperty(uriBase+"hasFirstName");
hasFirstName.setDomain(person);
hasFirstName.setRange(XSD.xstring);
(...)

does that work ?
ont.hasWife=model.createProperty("your namespace URI here","FAMhasWife");
StmtIterator iter = onto.model.listStatements(null,onto.hasWife,(RDFNode)null);
while (iter.hasNext()) {
Statement stmt = iter.nextStatement();
System.out.print(stmt.getObject().toString());
}

With the information you provide it's impossible to know what's the problem exactly. It is possible that you made a mistake in one of your URIs, either in your data or in your programme. Your question is inconcistent wrt naming terms.
May I suggest a few things? First, use the datatypes xsd:date or even xsd:dateTime for dates of marriage and dates of birth. Use the YYYY-MM-DD pattern for naming entities as this sorts them chronologically if sorted lexicographically. Use consistent naming convention, e.g., hasWife and hasHusband instead of hasWife and husband. "Marriage" has two "r" in English. Use a meaningful prefix when presenting your data to people. Better, use a human friendly syntax such as Turtle.
fam:BrunoCatherine a fam:Marriage;
fam:dateOfMarriage "2011-07-25"^^xsd:date;
fam:hasWife fam:Catherine1982-03-20;
fam:hasHusband fam:Bruno1980-06-15 .
fam:Catherine1982-03-20 fam:dateOfBirth "1982-03-20"^^xsd:date;
fam:hasLastName "Gomez";
fam:hasFirstName "Catherine" .
fam:Bruno1980-06-15 fam:dateOfBirth "1980-06-15"^^xsd:date;
fam:hasLastName "Jeandet";
fam:hasFirstName "Bruno" .
Doesn't it look nicer?

Related

Text normalization in python using Normalizer.Form.NFKD

A field in the table is normalized using Java as shown below,
String name = customerRecord.getName().trim();
name = name.replaceAll("œ", "oe");
name = name.replaceAll("æ", "ae");
name = Normalizer.normalize(name, Normalizer.Form.NFKD).replaceAll("[^\\p{ASCII}]", "");
name = name.toLowerCase();
Now I'm trying to query the same db using Python. How do I do Normalizer.normalize(name, Normalizer.Form.NFKD) in Python so that it is compatible with the way it is written to?
An almost complete translation of the above Java code to Python would be like as follows,
import unicodedata
ASCII_REPLACEMENTS = {
'œ': 'oe',
'æ': 'ae'
}
text = ''.join([ASCII_REPLACEMENTS.get(c, c) for c in search_term])
ascii_term = (
unicodedata.normalize('NFKD', text).
encode('ascii', errors='ignore').decode()
)
return ascii_term.lower()
ASCII_REPLACEMENTS should be amended with what ever characters that wont get translated correctly by unicodedata.normalize compared to Java's Normalizer.normalize(name, Normalizer.Form.NFKD). This way we can ensure the compatibility between the two.

Jena Model converts my RDF type explicit declaration to implicit and messes with the format

I have the following code that creates an RDF resource with some set properties and prints it on console.
String uri = "http://krweb/";
String name = "Giorgos Georgiou";
String phone = "6976067554";
String age = "27";
String department = "ceid";
String teaches = "java";
Model model = ModelFactory.createOntologyModel();
model.setNsPrefix("krweb", uri);
Resource giorgosgeorgiou = model.createResource(uri+name.toLowerCase().replace(" ", ""), model.createResource(uri+"Professor"));
Property has_name = model.createProperty(uri+"has_name");
Property has_phone = model.createProperty(uri+"has_phone");
Property has_age = model.createProperty(uri+"has_age");
Property member_of = model.createProperty(uri+"member_of");
Property teach = model.createProperty(uri+"teaches");
giorgosgeorgiou.addProperty(teach, model.createResource(uri+teaches));
giorgosgeorgiou.addProperty(member_of, model.createResource(uri+department));
giorgosgeorgiou.addProperty(has_age,age);
giorgosgeorgiou.addProperty(has_phone,phone);
giorgosgeorgiou.addProperty(has_name,name);
//giorgosgeorgiou.addProperty(RDF.type, model.createResource(uri+"Professor"));
model.write(System.out,"RDF/XML");
I want the model printed in this format:
<rdf:Description rdf:about="http://krweb/giorgosgeorgiou">
<rdf:type rdf:resource="http://krweb/Professor"/>
<krweb:has_name>Giorgos Georgiou</krweb:has_name>
<krweb:has_phone>6976067554</krweb:has_phone>
<krweb:has_age>27</krweb:has_age>
<krweb:member_of rdf:resource="http://krweb/ceid"/>
<krweb:teaches rdf:resource="http://krweb/java" />
</rdf:Description>
Instead I get this:
<krweb:Professor rdf:about="http://krweb/giorgosgeorgiou">
<krweb:has_name>Giorgos Georgiou</krweb:has_name>
<krweb:has_phone>6976067554</krweb:has_phone>
<krweb:has_age>27</krweb:has_age>
<krweb:member_of rdf:resource="http://krweb/ceid"/>
<krweb:teaches rdf:resource="http://krweb/java"/>
</krweb:Professor>
Somehow, the rdf type property gets converted to some implicit declaration and is presented in what I suppose is a "pretty" format. Is there a way to bypass this?
Internally the RDF data is held as triples - no knowledge of how they were formatted on input is stored.
The default output is pretty RDF/XML.
To get the plain, flat format use RDFFormat.RDFXML_PLAIN
RDFDataMgr.write(System.out, model, RDFFormat.RDFXML_PLAIN);

How to convert RDF Turtle into a Java Bean

I am currently learning about RDF and I am attempting to convert an RDF document into a Java Bean.
So far I have found and used the Jena library to read in an RDF Turtle document. I can then iterate over the statements within the Jena model and print out each statements subject, predicate and object. But instead I would like to convert/bind the RDF within the model to a Java bean.
Here is the code I am using to read the RDF Turtle into the Jena bean:
Model model = new ModelCom(new GraphMem());
model.read(new ByteArrayInputStream(body.getBytes()), null, "TURTLE");
Property predicate;
Statement statement;
Resource subject;
RDFNode obj;
StmtIterator iter = model.listStatements();
while(iter.hasNext()) {
statement = iter.next();
subject = statement.getSubject();
System.out.println("Subject = " + subject.getURI());
predicate = statement.getPredicate();
System.out.println("Predicate = " +predicate.getLocalName());
obj = statement.getObject();
System.out.println("Object = " + obj.toString());
}
I have tried for a couple of days, but I cannot find any documentation anywhere that demonstrates how to bind a model to a Java bean.
Ideally what I would like to do is:
Person person = model.read(Person.class);

Looping in Xpath Expression having Namespace

Suppose this my Sample XML with Namespaces
<data>
<vnfr:vnfr-catalog xmlns:vnfr="urn:ietf:params:xml:ns:yang:nfvo:vnfr">
<vnfr:vnfr>
<vnfr:id>1234</vnfr:id>
<vnfr:vdur>
<vnfr:id>987</vnfr:id>
<vnfr:id>987</vnfr:id>
<vnfr:management-ip>10.100.100.10</vnfr:management-ip>
</vnfr:vdur>
<vnfr:vdur>
<vnfr:id>567</vnfr:id>
<vnfr:id>567</vnfr:id>
<vnfr:management-ip>10.100.100.11</vnfr:management-ip>
</vnfr:vdur>
</vnfr:vnfr>
</vnfr:vnfr-catalog>
</data>
I have a sample Xpath expression which I use in Java
expression="/data/*[local-name() = 'vnfr-catalog']/*[local-name() = 'vnfr']/*[local-name() = 'id']/*[local-name() = 'vdur']/*[local-name() = 'management-ip']/text()";
Output: 10.100.100.10
But how to Iterate and fetch the 2nd management-ip i.e. 10.100.100.11
I tried the below expression with vdur[2] , but it didn't worked.
expression="/data/*[local-name() = 'vnfr-catalog']/*[local-name() = 'vnfr']/*[local-name() = 'id']/*[local-name() = 'vdur[2]']/*[local-name() = 'management-ip']/text()";
How to fetch the 2nd management IP using expression??????
Your query has two mistakes:
You should not get into id element since it does not contain management-ip, they are on the same level of hierarchy
*[local-name() = 'vdur[2]'] should be replaced with *[local-name() = 'vdur'][2]
Below is my query that seems working:
/data/vnfr:vnfr-catalog/vnfr:vnfr/vnfr:vdur[2]/vnfr:management-ip/text()
This is tested on
<data xmlns:vnfr="asdasdas">
<vnfr:vnfr-catalog>
<vnfr:vnfr>
<vnfr:id>1234</vnfr:id>
<vnfr:vdur>
<vnfr:id>987</vnfr:id>
<vnfr:id>987</vnfr:id>
<vnfr:management-ip>10.100.100.10</vnfr:management-ip>
</vnfr:vdur>
<vnfr:vdur>
<vnfr:id>567</vnfr:id>
<vnfr:id>567</vnfr:id>
<vnfr:management-ip>10.100.100.11</vnfr:management-ip>
</vnfr:vdur>
</vnfr:vnfr>
</vnfr:vnfr-catalog>
</data>
Above is your example but amended a bit since you are not declaring the namespace.
Output:
Text='10.100.100.11'
Tested in https://www.freeformatter.com/xpath-tester.html
Your correct query would look like this:
/data/*[local-name() = 'vnfr-catalog']/*[local-name() = 'vnfr']/*[local-name() = 'vdur'][2]/*[local-name() = 'management-ip']/text()
As Alexey resolve your one issue. below is the answer to getting the length of an attribute
While xxx is the tag prefix, use just count(//Formulas/yyy)
Use count keyword
Source
count of element in XPath
Hope it will help you :)

How to get text from app engine datastore?

Can someone please tell me how to get a Text value out of a Google App Engine datastore using Java? I have some entities in the datastore with a Text property named longDescription. When I try this:
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("Items");
PreparedQuery pq = ds.prepare(q);
for (Entity result : pq.asIterable()) {
Text longDescription = (Text)result.getProperty("longDescription");
}
I'm getting this warning on the longDescription assignment line:
WARNING: /pstest
java.lang.ClassCastException: java.lang.String cannot be cast to
com.google.appengine.api.datastore.Text
I'm absolutely bumfuzzled here. The only string in my code is the literal "longDescription" that is used to fetch the correct property. If I put this just above the assignment line:
log.warning("Type is " + (result.getProperty("longDescription")).getClass());
I see the following output:
WARNING: Type is class com.google.appengine.api.datastore.Text
Okay, so result.getProperty("longDescription") really, really is a Text object that is being passed back as an object. I've even tried using the fully qualified name (com.google.appengine.api.datastore.Text) instead of just Text with the same results. Where is the String cast coming in? And more importantly, how do I get that Text out of the datastore? I'm at my wit's end here, and any help would be appreciated!
Oh, one other possibly relevant note: This is the assignment I used when inserting the property into the datastore:
Entity eItem = new Entity("Items");
eItem.setProperty("longDescription", new Text(req.getParameter("ldes")));
ds.put(eItem);
When I look at the description in my management console, it seems to be over 500 characters, and it's displayed like this:
<Text: This is a long form description of an item in the store that is access...>
Did I screw something up when inserting it? If so, how do you insert Text items into the datastore?
I figured out the problem, Wei Hao was right in the comments above. It seems that at some point, I inserted a test String as a longDescription instead of a Text. I'm going to chalk this up to being a lesson learned from the school of hard knocks due to being a bit of a noob with the datastore.
For anyone else who runs across this question, the answer is: If you're iterating over a list of query results, make sure that you're getting back what you expect on every result that comes back! Remember, this isn't an RDBMS and every entity can have a different datatype for the same property. So yes, you can have 1,572,394 entities in which longDescription is a Text and one entity in which longDescription is a String, and this will hose you up.
Here's a little code snippet that probably would help to diagnose this issue:
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Query q = new Query("Items");
PreparedQuery pq = ds.prepare(q);
for (Entity result : pq.asIterable()) {
if (longDescription isinstanceof Text)
Text longDescription = (Text)result.getProperty("longDescription");
else
log.severe("Unexpected datatype: longDescription is a "
+ result.getProperty("longDescription").getClass().toString());
}
Here's my code;
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Query q = new Query(entityKind);
PreparedQuery pq = ds.prepare(q);
for (Entity e : pq.asIterable()) {
String longtext = ((Text)e.getProperty("somelongdescription")).getValue();}

Categories