From: Rob V. <ra...@ec...> - 2010-04-21 13:10:11
|
Hi Erika I'm not surprised you've had trouble with the OpenCalais RDF since it is rather complex and has taken me quite some time just to start figuring out how to get the information you wanted. Sorry for delay in replying but I wanted to give you as good an answer as I could. Firstly since Person nodes are URIs and will be things of type Person you need to be using the various GetTriples...() methods combined with the CreateUriNode() method e.g. Graph g = new Graph(); StringParser.Parse(g, document.RawOutput, new RdfXmlParser()); UriNode person = g.CreateUriNode(new Uri("http://s.opencalais.com/1/type/em/e/Person")); Note that in all my examples here you could replace the use of CreateUriNode() with GetUriNode(), the difference being that GetUriNode() returns null if the given Node is not found in the Graph which may not always be desirable and will require you to check each Node you need is non-null. Also CreateUriNode() will be quicker than GetUriNode(), GetUriNode() is more useful for determining if a given Node exists in a Graph. Creating the Node in the previous example only creates a Node which represents the type Person, what you are actually interested in are the actual instances of person which will be things which have a triple defining them to be of type person. Once you have the nodes which represent the actual instances of Person then you can then use that node to find further information e.g. //This example would require using VDS.RDF.Parsing; at the top of your code file //Create a node for rdf:type and use it to look up all instances of type Person UriNode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType)); foreach (Triple t in g.GetTriplesWithPredicateObject(rdfType, person)) { //Now you can do something with each Person //The Subject of the Triple is the Node that represents an instance of a Person Console.WriteLine(t.Subject.ToString()); } The following is a sample console application which finds what you are after, sorry that it's so horribly complex but the RDF is really rather complex: using System; using System.Collections.Generic; using System.Linq; using System.Text; using VDS.RDF; using VDS.RDF.Parsing; namespace opencalais_sample { class Program { static void Main(string[] args) { Graph g = new Graph(); FileLoader.Load(g, "opencalais.rdf"); //First create the rest of the Nodes we need UriNode person = g.CreateUriNode(new Uri("http://s.opencalais.com/1/type/em/e/Person")); UriNode rdfType = g.CreateUriNode(new Uri(RdfSpecsHelper.RdfType)); UriNode personEmailAddr = g.CreateUriNode(new Uri("http://s.opencalais.com/1/type/em/r/PersonEmailAddress")); UriNode personRelation = g.CreateUriNode(new Uri("http://s.opencalais.com/1/pred/person")); UriNode emailAddrRelation = g.CreateUriNode(new Uri("http://s.opencalais.com/1/pred/emailaddress")); UriNode name = g.CreateUriNode(new Uri("http://s.opencalais.com/1/pred/name")); //Then try and select the things we are interested in foreach (Triple t in g.GetTriplesWithPredicateObject(rdfType, person)) { //The Subject of each of these Triples will be an instance of a Person //Now we want to find PersonEmailAddresses for these people foreach (Triple t2 in g.GetTriplesWithPredicateObject(personRelation, t.Subject)) { //These are things that are related to the people we have found //Ensure that they are of type PersonEmailAddress if (g.ContainsTriple(new Triple(t2.Subject, rdfType, personEmailAddr))) { //Now we can find the related email address foreach (Triple t3 in g.GetTriplesWithSubjectPredicate(t2.Subject, emailAddrRelation)) { //Then find the actual email address foreach (Triple t4 in g.GetTriplesWithSubjectPredicate(t3.Object, name)) { Console.WriteLine("Person = " + t.Subject + " Email = " + t4.Object); } } } } } Console.ReadLine(); } } } You could alternatively find the same information with the following SPARQL Query, explicit nested Graph Patterns have been used to eliminate duplicates which would otherwise be introduced. SELECT ?person ?email WHERE { ?person a <http://s.opencalais.com/1/type/em/e/Person> . { ?x <http://s.opencalais.com/1/pred/person> ?person . ?x a <http://s.opencalais.com/1/type/em/r/PersonEmailAddress> . ?x <http://s.opencalais.com/1/pred/emailaddress> ?addr . } { ?addr <http://s.opencalais.com/1/pred/name> ?email } } You can execute SPARQL Queries against a Graph by using the ExecuteQuery() extension method e.g. //This example will require using VDS.RDF.Query; at the top of your code file //We use a verbatim string so it can go over several lines and preserve the formatting (prefixed with the @ character) String query = @"SELECT ?person ?email WHERE { ?person a <http://s.opencalais.com/1/type/em/e/Person> . { ?x <http://s.opencalais.com/1/pred/person> ?person . ?x a <http://s.opencalais.com/1/type/em/r/PersonEmailAddress> . ?x <http://s.opencalais.com/1/pred/emailaddress> ?addr . } { ?addr <http://s.opencalais.com/1/pred/name> ?email } }"; Object results = g.ExecuteQuery(query); if (results is SparqlResultSet) { SparqlResultSet rset = (SparqlResultSet)results; foreach (SparqlResult r in rset) { Console.WriteLine(r.ToString()); } } Your third option is to use the Ontology API instead which is more resource centric and may make more sense to you, this is still rather complex though because of the nature of the RDF in question: using System; using System.Collections.Generic; using System.Linq; using System.Text; using VDS.RDF; using VDS.RDF.Parsing; using VDS.RDF.Ontology; class Program2 { static void Main(string[] args) { OntologyGraph g = new OntologyGraph(); FileLoader.Load(g, "opencalais.rdf"); //Get the Classes and Resources we need OntologyClass personClass = g.CreateOntologyClass(new Uri("http://s.opencalais.com/1/type/em/e/Person")); OntologyClass personEmailAddr = g.CreateOntologyClass(new Uri("http://s.opencalais.com/1/type/em/r/PersonEmailAddress")); OntologyClass emailAddrClass = g.CreateOntologyClass(new Uri("http://s.opencalais.com/1/type/em/e/EmailAddress")); OntologyProperty personRelation = g.CreateOntologyProperty(new Uri("http://s.opencalais.com/1/pred/person")); OntologyProperty emailAddrRelation = g.CreateOntologyProperty(new Uri("http://s.opencalais.com/1/pred/emailaddress")); OntologyProperty nameRelation = g.CreateOntologyProperty(new Uri("http://s.opencalais.com/1/pred/name")); //Get the PersonEmailAddress instances foreach (OntologyResource emailAddress in personEmailAddr.Instances) { //Get the People related to this email address by the person relation foreach (Triple t in g.GetTriplesWithSubjectPredicate(emailAddress.Resource, personRelation.Resource)) { //Now try and get this individual which is a Person Individual person = g.CreateIndividual(t.Object, personClass.Resource); //And finally get the actual email address foreach (Triple t2 in g.GetTriplesWithSubjectPredicate(emailAddress.Resource, emailAddrRelation.Resource)) { //Create the individual email address Individual email = g.CreateIndividual(t2.Object, emailAddrClass.Resource); //Get the actual textual value of the email address foreach (Triple t3 in g.GetTriplesWithSubjectPredicate(email.Resource, nameRelation.Resource)) { Console.WriteLine("Person = " + person.ToString() + " Email = " + t3.Object.ToString()); } } } } Console.ReadLine(); } } Hope that helps you somewhat, if you can't follow that I would suggest trying to find some simpler RDF to work with to help you learn how to navigate RDF Graphs. If you need further help please let me know. Rob Vesse From: Erika L. Borg [mailto:eri...@gm...] Sent: 20 April 2010 23:04 To: dot...@li... Subject: [Dotnetrdf-support] help needed in accessing node Hi, I'm very sorry to disturb but i'm very very new to RDF and dotnetRDF and was wondering if you could help me out on this issue. I have an RDF such as the following (output from the OpenCalais .NET project) but i cant seem to find a way to access the nodes i require. I have been trying all day to no avail :s a sample RDF is attached Graph gra = new Graph(); StringParser.Parse(gra, document.RawOutput,new RdfXmlParser()); LiteralNode l = gra.GetLiteralNode("person"); textBox1.Text += "/n"+ l.ToString(); I'm trying to access the Person nodes for instance and then subsequently the PersonEmailAddress node which containes both person and emailaddress field (so i guess its like a perant node?). i cant seem to find a way to access these nodes due to my inexperience with SPARQL and RDF. I would really really really appreciate your assistance as i'm really not sure what i should be doing =/ if you could point me out on the right direction with person and PersonEmailAddress i should be able to understnad whats going on. I would really really appreciate your help on this matter as i've been going through the guide all day long and trying different sorts of code but cant seem to get to the right thing Looking forward to hearing from you, Best Regards, Erika Borg P.S: thank you for such a wonderful RDF api in .net which is so flexible <3 |