1.21 RDF Graph Management Examples (PL/SQL and Java)

PL/SQL examples are provided in this topic.

For Java examples, see RDF Graph Support for Apache Jena.

1.21.1 Example: Journal Article Information

This section presents a simplified PL/SQL example of RDF graph for statements about journal articles. Example 1-129 contains descriptive comments, refers to concepts that are explained in this chapter, and uses functions and procedures documented in SEM_APIS Package Subprograms.

Example 1-129 Using an RDF Graph for Journal Article Information

-- Basic steps:
-- After you have connected as a privileged user and called 
-- SEM_APIS.CREATE_RDF_NETWORK to create a schema for storing RDF data,
-- connect as a regular database user and do the following.

-- 1. For each desired network, create an RDF graph(SEM_APIS.CREATE_RDF_GRAPH). 
-- Note that we are using the schema-private network NET1 created in 
-- "Quick Start for Using RDF Data".

EXECUTE SEM_APIS.CREATE_RDF_GRAPH('articles', 'null', 'null', network_owner=>'RDFUSER', network_name=>'NET1');
 
-- Information to be stored about some fictitious articles:
-- Article1, titled "All about XYZ" and written by Jane Smith, refers 
--   to Article2 and Article3.
-- Article2, titled "A review of ABC" and written by Joe Bloggs, 
--   refers to Article3.
-- Seven SQL statements to store the information. In each statement:
-- Each article is referred to by its complete URI The URIs in
--   this example are fictitious.
-- Each property is referred to by the URL for its definition, as 
--   created by the Dublin Core Metadata Initiative.
 
-- 2. Use SEM_APIS.UPDATE_RDF_GRAPH to insert data with SPARQL Update statements
 
BEGIN
  SEM_APIS.UPDATE_RDF_GRAPH('articles',
   'PREFIX  nature: <http://nature.example.com/>
    PREFIX      dc: <http://purl.org/dc/elements/1.1/>
    PREFIX dcterms: <http://purl.org/dc/terms/>

    INSERT DATA {

      # article1 has the title "All about XYZ".
      # article1 was created (written) by Jane Smith.
      # article1 references (refers to) article2 and article3
      nature:article1 dc:title "All about XYZ" ;
                      dc:creator "Jane Smith" ;
                      dcterms:references nature:article2, 
                                         nature:article3 . 

      # article2 has the title "A review of ABC".
      # article2 was created (written) by Joe Bloggs.
      # article2 references (refers to) article3.                    
      nature:article2 dc:title "A Review of ABC" ;
                      dc:creator "Joe Bloggs" ;
                      dcterms:references nature:article3 .
    }',
   network_owner=>'RDFUSER',
   network_name=>'NET1');   
END;
/

-- 3. Query RDF data with SEM_MATCH table function.
-- 3.a Get all article authors and titles
SELECT author$rdfterm, title$rdfterm
FROM TABLE(SEM_MATCH(
'PREFIX dc: <http://purl.org/dc/elements/1.1/>
 SELECT ?author ?title
 WHERE { ?article dc:creator ?author
                ; dc:title  ?title . }'
, SEM_MODELS('articles')
, null, null, null, null
, ' PLUS_RDFT=VC '
, null, null
, 'RDFUSER', 'NET1'));

-- 3.b Find all articles referenced by Article1
SELECT ref$rdfterm
FROM TABLE(SEM_MATCH(
'PREFIX dcterms: <http://purl.org/dc/terms/>
 PREFIX  nature: <http://nature.example.com/>
 SELECT ?ref
 WHERE { nature:article1 dcterms:references ?ref . }'
, SEM_MODELS('articles')
, null, null, null, null
, ' PLUS_RDFT=VC '
, null, null
, 'RDFUSER', 'NET1'));

1.21.2 Example: Family Information

This section presents a simplified PL/SQL example of an RDF graph for statements about family tree (genealogy) information. Example 1-129 contains descriptive comments, refers to concepts that are explained in this chapter, and uses functions and procedures documented in SEM_APIS Package Subprograms.

The family relationships in this example reflect the family tree shown in Figure 1-3. This figure also shows some of the information directly stated in the example: Cathy is the sister of Jack, Jack and Tom are male, and Cindy is female.

Figure 1-3 Family Tree for RDF Example

Description of Figure 1-3 follows
Description of "Figure 1-3 Family Tree for RDF Example"

Example 1-130 Using an RDF graph for Family Information

-- Preparation: create tablespace; enable RDF support.
-- Connect as a privileged user. Example: CONNECT SYSTEM/password-for-SYSTEM
-- Create a tablespace for the RDF data. Example:
CREATE TABLESPACE rdf_tblspace 
  DATAFILE 'rdf_tblspace.dat' 
    SIZE 128M REUSE
    AUTOEXTEND ON NEXT 128M MAXSIZE 4G
  SEGMENT SPACE MANAGEMENT AUTO;

-- Call SEM_APIS.CREATE_RDF_NETWORK to create a schema-private RDF
-- network named NET1 owned by RDFUSER, which will create database
-- objects to store RDF data. Example:
EXECUTE SEM_APIS.CREATE_RDF_NETWORK('rdf_tblspace', network_owner=>'RDFUSER', network_name=>'NET1');

-- Connect as the user that is to perform the RDF operations (not SYSTEM), 
-- and do the following:
-- 1. For each desired network, create an RDF graph (SEM_APIS.CREATE_RDF_GRAPH).
-- 2. Use various subprograms and constructors.
-- Create the RDF graph.EXECUTE SEM_APIS.CREATE_RDF_GRAPH('family', 'null', 'null', network_owner=>'RDFUSER', network_name=>'NET1');
 
-- Insert RDF triples using SEM_APIS.UPDATE_RDF_GRAPH. These express the following information:
-----------------
-- John and Janice have two children, Suzie and Matt.
-- Matt married Martha, and they have two children:
--   Tom (male) and Cindy (female).
-- Suzie married Sammy, and they have two children:
--   Cathy (female) and Jack (male).
 
-- Person is a class that has two subslasses: Male and Female.
-- parentOf is a property that has two subproperties: fatherOf and motherOf.
-- siblingOf is a property that has two subproperties: brotherOf and sisterOf.
-- The domain of the fatherOf and brotherOf properties is Male.
-- The domain of the motherOf and sisterOf properties is Female.
------------------------
 
BEGIN

  -- Insert some TBox (schema) information.
  SEM_APIS.UPDATE_RDF_GRAPH('family',
   'PREFIX    rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX   rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX family: <http://www.example.org/family/>

    INSERT DATA {

      # Person is a class.
      family:Person rdf:type rdfs:Class .

      # Male is a subclass of Person.
      family:Male rdfs:subClassOf family:Person .
 
      # Female is a subclass of Person. 
      family:Female rdfs:subClassOf family:Person .

      # siblingOf is a property.
      family:siblingOf rdf:type rdf:Property .
 
      # parentOf is a property.
      family:parentOf rdf:type rdf:Property .
 
      # brotherOf is a subproperty of siblingOf.
      family:brotherOf rdfs:subPropertyOf family:siblingOf .

      # sisterOf is a subproperty of siblingOf.
      family:sisterOf rdfs:subPropertyOf family:siblingOf .
 
      # A brother is male.
      family:brotherOf rdfs:domain family:Male .
 
      # A sister is female.
      family:sisterOf rdfs:domain family:Female .

      # fatherOf is a subproperty of parentOf.
      family:fatherOf rdfs:subPropertyOf family:parentOf .
 
      # motherOf is a subproperty of parentOf.
      family:motherOf rdfs:subPropertyOf family:parentOf .

      # A father is male.
      family:fatherOf rdfs:domain family:Male .
 
      # A mother is female.
      family:motherOf rdfs:domain family:Female .
    }',
   network_owner=>'RDFUSER',
   network_name=>'NET1');

  -- Insert some ABox (instance) information.
  SEM_APIS.UPDATE_RDF_GRAPH('family',
   'PREFIX    rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX   rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX family: <http://www.example.org/family/>

    INSERT DATA {
      # John is the father of Suzie and Matt
      family:John family:fatherOf family:Suzie .
      family:John family:fatherOf family:Matt .

      # Janice is the mother of Suzie and Matt
      family:Janice family:motherOf family:Suzie .
      family:Janice family:motherOf family:Matt .

      # Sammy is the father of Cathy and Jack
      family:Sammy family:fatherOf family:Cathy .
      family:Sammy family:fatherOf family:Jack .

      # Suzie is the mother of Cathy and Jack
      family:Suzie family:motherOf family:Cathy .
      family:Suzie family:motherOf family:Jack .

      # Matt is the father of Tom and Cindy
      family:Matt family:fatherOf family:Tom .
      family:Matt family:fatherOf family:Cindy .

      # Martha is the mother of Tom and Cindy
      family:Martha family:motherOf family:Tom .
      family:Martha family:motherOf family:Cindy .

      # Cathy is the sister of Jack
      family:Cathy family:sisterOf family:Jack .

      # Jack is male
      family:Jack rdf:type family:Male .

      # Tom is male.
      family:Tom rdf:type family:Male .

      # Cindy is female.
      family:Cindy rdf:type family:Female .
    }',
   network_owner=>'RDFUSER',
   network_name=>'NET1');

END;
/


-- RDFS inferencing in the family RDF graph
BEGIN
  SEM_APIS.CREATE_INFERRED_GRAPH(
    'rdfs_rix_family',
    SEM_Models('family'),
    SEM_Rulebases('RDFS'),
    network_owner=>'RDFUSER',
    network_name=>'NET1');
END;
/
 
-- Select all males from the family graph, without inferencing.
-- (Returns only Jack and Tom.)
SELECT m$rdfterm
  FROM TABLE(SEM_MATCH(
    'PREFIX  rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
     PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
     PREFIX     : <http://www.example.org/family/>
     SELECT ?m
     WHERE {?m rdf:type :Male}',
    SEM_Models('family'),
    null,  null,  null, null,
    ' PLUS_RDFT=VC ',
    null, null,
    'RDFUSER', 'NET1'));
 
-- Select all males from the family graph, with RDFS inferencing.
-- (Returns Jack, Tom, John, Sammy, and Matt.)
SELECT m$rdfterm
  FROM TABLE(SEM_MATCH(
    'PREFIX  rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
     PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
     PREFIX     : <http://www.example.org/family/>
     SELECT ?m
     WHERE {?m rdf:type :Male}',
    SEM_Models('family'),
    SEM_Rulebases('RDFS'), 
    null, null, null,
    ' PLUS_RDFT=VC ',
    null, null,
    'RDFUSER', 'NET1'));
 
-- General inferencing in the family graph
 
EXECUTE SEM_APIS.CREATE_RULEBASE('family_rb', network_owner=>'RDFUSER', network_name=>'NET1');
 
INSERT INTO rdfuser.net1#semr_family_rb VALUES(
  'grandparent_rule',
  '(?x :parentOf ?y) (?y :parentOf ?z)',
  NULL,
  '(?x :grandParentOf ?z)', 
  SEM_ALIASES(SEM_ALIAS('','http://www.example.org/family/')));
 
COMMIT;
 
-- Because a new rulebase has been created, and it will be used in the
-- inferred graph, drop the preceding inferred graph and then re-create it.
EXECUTE SEM_APIS.DROP_INFERRED_GRAPH ('rdfs_rix_family', network_owner=>'RDFUSER', network_name=>'NET1');
 
-- Re-create the inferred graph.
BEGIN
  SEM_APIS.CREATE_INFERRED_GRAPH(
    'rdfs_rix_family',
    SEM_Models('family'),
    SEM_Rulebases('RDFS','family_rb'), 
    network_owner=>'RDFUSER', network_name=>'NET1');
END;
/
 
-- Select all grandfathers and their grandchildren from the family graph, 
-- without inferencing. (With no inferencing, no results are returned.)
SELECT x$rdfterm grandfather, y$rdfterm grandchild
  FROM TABLE(SEM_MATCH(
    'PREFIX  rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
     PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
     PREFIX     : <http://www.example.org/family/>
     SELECT ?x ?y
     WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}',
    SEM_Models('family'),
    null, null,  null, null,
    ' PLUS_RDFT=VC ',
    null, null,
    'RDFUSER', 'NET1'));
 
-- Select all grandfathers and their grandchildren from the family graph.
-- Use inferencing from both the RDFS and family_rb rulebases.
SELECT x$rdfterm grandfather, y$rdfterm grandchild
  FROM TABLE(SEM_MATCH(
    'PREFIX  rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
     PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
     PREFIX     : <http://www.example.org/family/>
     SELECT ?x ?y
     WHERE {?x :grandParentOf ?y . ?x rdf:type :Male}',
    SEM_Models('family'),
    SEM_Rulebases('RDFS','family_rb'), 
    null,  null, null,
    ' PLUS_RDFT=VC ',
    null, null,
    'RDFUSER', 'NET1'));