본문 바로가기

기술

Jena RDF API

Jena API를 위한 RDF 간략 소개

RDF를 그래프로 표현하면 아래와 같다.

아래의 원 모양의 그림을 Resource, 사각형을 Literal 그리고 화살표를 Property 라고 부른다.

fig1.png

Resource가 가지는 http://.. 라는 값은 URI라고 불리운다.

Resource(http://..)는 property(vcard:FN)를 갖게되고, property는 "John Smith"라는 값을 갖는데 이는 Literal 형식의 데이터로 표현되어 있다.

하지만 property는 Listeral 형식의 데이터뿐만 아니라 Resource를 가질수도 있다.


RDF를 그래프로 표현한 표현한 그림에서 각각의 모양(원, 화살표, 사각형)을 Statement라 부른다.

Statement or Triple

Subject : 그림에서 화살표가 시작된 곳(그림에서는 원), 즉 Resource를 말한다.

predicate : property라고 부르는 화살표를 말한다.

object : literal이나 혹은 또 다른 Resource가 될 수 있으며 그림에서는 화살표가 가리키는 타켓을 말한다.



아래 그림은 Jena RDF API 튜토리얼에서 제공하는 VCARD RDF Schema로 작성된 John Smith에 대한 RDF 그래프 모델이다.

fig2.png

Resource는 보통 URI로 표현되어지기도 하지만 vcard:N property가 가지는 리소스처럼 URI를 가지지 않는 Resource도 존재한다. 이를 blank node라고 부른다.


Jena RDF API 에서는 위처럼 그래프로 표현되어 지는 것들을 model이라 부르며, 이는 Model 이라는 Java Interface를 통해 표현되어 진다.


Create new model

  1. // 변수 값 정의
    String personURI    = "http://somewhere/JohnSmith";
    String givenName    = "John";
    String familyName   = "Smith";
    String fullName     = givenName + " " + familyName;

    // 비어있는 새로운 Model을 생성한다.
    Model model = ModelFactory.createDefaultModel();

    Resource johnSmith
      = model.createResource(personURI)  //model에 personURI 변수값을 갖는 Resource를 생성한다.
  2.           //생성된 Resource(personURI)에  VCARD.FN이라는 Property를 추가하고 이 Property는 fullName값을 갖는다.
             .addProperty(VCARD.FN, fullName)
             .addProperty(VCARD.N,
  3. // Resource(personURI)에 VCARD.N이라는 Property를 추가하고 이 Property는 URI값을 갖지 않는 Resource(Blank Node)를 갖는다.
  4. model.createResource()
  5.          //생성된 Blank Node에 VCARD.Given 이라는 Property를 추가하고 그 Property는 givenName값을 갖는다.
             .addProperty(VCARD.Given, givenName)
  6.          //생성된 Blank Node에 VCARD.Family라는 Property를 추가하고 그 Property는 familyName값을 갖는다.
  7.    .addProperty(VCARD.Family, familyName));


Read & Write in RDF

  • Jena에서는 RDF를 읽기 위한 다양한 인터페이스를 제공한다. URL과 File을 통해서 RDF를 Model로 Load할 수 있다.
  1. Model model= ModelFactory.createDefaultModel();
    model.read("file:c:/test/test.rdf");    //URL 형태로 RDF를 로드한다.


  • Model을 write하기 위해 java.ioOupteStream, java.io.Writer 인터페이스를 이용한다.

  1. model.write(System.out, "RDF/XML"); // RDF/XML 형태로 System.out 을 통해 model을 쓴다.
  2. Model.write(new PrintWriter(new FileOutputStream("c:/test/test.rdf")), "RDF/XML");    //RDF/XML 형태로 test.rdf파일에 model을 쓴다.
  • Model을 저장하기 위한 형태로는 RDF/XML", "RDF/XML-ABBREV", "N-TRIPLE", "TURTLE", (and "TTL") , "N3"가 있고, 정의하지 않으면 "RDF/XML"형태로 저장된다.


Controlling Prefixes


<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vCard='http://www.w3.org/2001/vcard-rdf/3.0#'>

RDF의 Prefix부분


  1. // Model을 생성한다.
  2.  Model m = ModelFactory.createDefaultModel();
     String nsA = "http://somewhere/else#";
     String nsB = "http://nowhere/else#";
     Resource root = m.createResource( nsA + "root" );
     Property P = m.createProperty( nsA + "P" );
     Property Q = m.createProperty( nsB + "Q" );
     Resource x = m.createResource( nsA + "x" );
     Resource y = m.createResource( nsA + "y" );
     Resource z = m.createResource( nsA + "z" );
     m.add( root, P, x ).add( root, P, y ).add( y, Q, z );
  3. // nsA(http://somewhere/else#)
    URI에 nsA라고 Prefix를 정의한다.
     m.setNsPrefix( "nsA", nsA );
  4. // prefix는 아래와 같이 삭제할 수 있다.
  5. m.removePrefix("nsA");


Prefix를 정의하지 않은 경우 nsA를 prefix로 정의한 경우
<rdf:RDF
    xmlns:j.0="http://nowhere/else#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:j.1="http://somewhere/else#" >
  <rdf:Description rdf:about="http://somewhere/else#root">
    <j.1:P rdf:resource="http://somewhere/else#x"/>
    <j.1:P rdf:resource="http://somewhere/else#y"/>
  </rdf:Description>
  <rdf:Description rdf:about="http://somewhere/else#y">
    <j.0:Q rdf:resource="http://somewhere/else#z"/>
  </rdf:Description>
</rdf:RDF>
<rdf:RDF
    xmlns:j.0="http://nowhere/else#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:nsA="http://somewhere/else#" >
  <rdf:Description rdf:about="http://somewhere/else#root">
    <nsA:P rdf:resource="http://somewhere/else#x"/>
    <nsA:P rdf:resource="http://somewhere/else#y"/>
  </rdf:Description>
  <rdf:Description rdf:about="http://somewhere/else#y">
    <j.0:Q rdf:resource="http://somewhere/else#z"/>
  </rdf:Description>
</rdf:RDF>


Navigating a Model

Get all statement list from a Model.

  • Model이 가지고 있는 모든 statement의 set을 얻는다.


  1. // Model에서 Statement의 전체 List를 얻는다.
    StmtIterator iter = model.listStatements();

    while (iter.hasNext()) {
        Statement stmt      = iter.nextStatement();  // get next statement
        Resource  subject   = stmt.getSubject();     // get the subject
        Property  predicate = stmt.getPredicate();   // get the predicate
        RDFNode   object    = stmt.getObject();      // get the object (
    Resource 혹은 Literal형의 데이터 타입을 갖는다.)
  2. }


Deal with accessing information in a Model.

  • Model에서 원하는 정보를 찾아서 다룬다.


<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vCard='http://www.w3.org/2001/vcard-rdf/3.0#'>


  <rdf:Description rdf:about="http://somewhere/MattJones/">
    <vCard:FN>Matt Jones</vCard:FN>
    <vCard:N vCard:Family="Jones" vCard:Given="Matthew"/>
  </rdf:Description>


</rdf:RDF>

Sample RDF Data


  1. Resource vcard = model.getResource("http://somewhere/MattJones/");

    RDFNode node = vcard.getProperty(VCARD.N).getObject();
    if(node instanceof Resource){
       Resource n = (Resource) node;
       RDFNode no = n.getProperty(VCARD.Given).getObject();
    }



Querying a Model

  • 모델에서 원하는 정보를 탐색한다. Jena RDF API에서는 제한적인 쿼리만을 제공하고, 보다 더 강력한 query를 만들고 싶다면 RDQL을 참고한다.


  1. ResIterator resIter = model.listSubjects();   //모든 subject를 가져온다.
    while(resIter.hasNext()){
       Resource r = resIter.nextResource();
       System.out.println(r);
    }
           
    ResIterator resIter2 = model.listSubjectsWithProperty(VCARD.FN);   //VCARD.FN property를 갖는 모든 Subject 를 가져온다.
    while(resIter2.hasNext()){
       Resource r = resIter2.nextResource();
    }

  2. //Selector를 이용하여 Query 만들기
  3. //Selector 인스턴스에 subject, predicate, object를 설정한다.
  4. Selector selector = new SimpleSelector(subject, predicate, object); //항목에 null을 설정하게 되면 해당 항목에 대해 전체 질의를 하게 된다.
  5. model.listStatements(selector);   //selector에 정의된 S P O 에 해당하는 statement set을 가져온다.


SimpleSelectorAPI.png


Operations on Models

  • Model에 대해 union, intersection, difference 연산을 지원한다.


  1. Model model1 = ....;
  2. Model model2 = ....;
    //두 모델의 Union 연산하기
    Model unionModel = model1.union(model2);   //model1 과 model2를 union하여 새로운 model을 만든다.
  3. Model diffModel = model1.difference(model2);   //model1 과 model2를 different하여 새로운 model을 만든다.
  4. Model intersectionModel = model1.intersection(model2);   //model1 과 model2를 intersection하여 새로운 model을 만든다.


Union Example

fig4.png union fig5.png = fig6.png



Containers

  • Collection 형태로 나타나는 특별한 형태의 Resource를 일컫는다. 예를 들면 책을 쓴 저자의 목록이라던가 오페라 단원들 멤버의 목록같은것을 표현한다.
  • Bag : 정렬되지 않는 값들의 리스트.
<rdf:Description
 rdf:about="http://www.recshop.fake/cd/Beatles">
 <cd:artist>
   <rdf:Bag>
     <rdf:li>John</rdf:li>
     <rdf:li>Paul</rdf:li>
     <rdf:li>George</rdf:li>
     <rdf:li>Ringo</rdf:li>
   </rdf:Bag>
  </cd:artist>
</rdf:Description>


  • Seq : 정렬된 값들의 리스트(알파벳이나, 숫자)
<rdf:Description
 rdf:about="http://www.recshop.fake/cd/Beatles">
 <cd:artist>   
   <rdf:Seq>
     <rdf:li>George</rdf:li>
     <rdf:li>John</rdf:li>
     <rdf:li>Paul</rdf:li>
     <rdf:li>Ringo</rdf:li>
   </rdf:Seq>
  </cd:artist>
</rdf:Description>


  • Alt : 선택할 수 있는 값들의 목록 <rdf:Alt>로 정의되어 있다면 해당 값들중에 하나를 선택해야 한다는 의미이다.
<rdf:Description
 rdf:about="http://www.recshop.fake/cd/Beatles">
 <cd:format>   
   <rdf:Alt>
     <rdf:li>CD</rdf:li>
     <rdf:li>Record</rdf:li>
     <rdf:li>Tape</rdf:li>
   </rdf:Alt>
  </cd:format>
</rdf:Description>

 

예제

  1. Bag bag = model.createBag();
    bag.add("Remeo and Juliet").add("Hamlet").add("Othello");
    model.write(System.out);

결과

<rdf:Description rdf:nodeID="A4">
    <rdf:_3>Othello</rdf:_3>
    <rdf:_2>Hamlet</rdf:_2>
    <rdf:_1>Remeo and Juliet</rdf:_1>
    <rdf:type rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag"/>
  </rdf:Description>






이 글은 스프링노트에서 작성되었습니다.

'기술' 카테고리의 다른 글

Web Framework - 웹어플리케이션 개발을 보다 쉽게..  (0) 2012.02.20
Modernizr  (0) 2012.02.15
RDF Schema - simple graph  (0) 2012.02.14