1. About Apache Jena

2024. 1. 18. 16:34OpenSource/Apache Jena

반응형

안녕하세요
오늘은 아파치 제나에 대해서 알아보겠습니다 ㅎㅎ
A free and open source Java framework for building Semantic Web and Linked Data applications.
아파치 제나는 시멘틱웹과 링크드데이터 어플리케이션을 만들수 있는 자바프레임워크 오픈소스 입니다.

앞으로 학습이 되어야 이해가 될 용어들이 많이 보이는군요!
RDF, SPARQL, TDB, Fuseki, OWL etc.

우선 아래의 아키텍처를 살펴보겠습니다.

우선 Fuseki라는것이 보이고 SPARQL API를 찌르는게 보이네요 그리고나서 Inference API, Store API 
parsers and writers 등등 느낌이 올랑말랑하네요 ㅎㅎ

 

아키텍처에 나온 전체적인 내용을 전부 정리하지는 않고 콕콕 찝어서 정리 하도록 하겠습니다.
RDF, SPARQL, Ontology 등등이 보이는데 이번 포스팅에서는 RDF 입니다.
더 나아가 다른 포스틍에서는 Fuseki, TDB 등등~을 살펴보겠습니다.

START

우선 RDF모델을 모르고 개발하면 노잼이라고 합니다. 물론 모델만 학습하는것은 의미없가 없으니
둘다 학습해서 재미를 느껴보라고 하네요!

https://jena.apache.org/tutorials/rdf_api.html

 

Apache Jena - An Introduction to RDF and the Jena RDF API

Preface This is a tutorial introduction to both W3C’s Resource Description Framework (RDF) and Jena, a Java API for RDF. It is written for the programmer who is unfamiliar with RDF and who learns best by prototyping, or, for other reasons, wishes to move

jena.apache.org

오늘 학습할 내용은 RDF 및 Jena RDF API를 간단하게 소개하는 내용 입니다.
RDF data model은 Resource Description Framework (RDF)인데요
XML의 구문이 있는데 더 중요한것은 RDF는 데이터모델 측면에서 이해해야 합니다.
다시말해 RDF 데이터는 XML로 표현되는데 이 구문을 이해하는 것보다 데이터 모델을 이해하는것이 우선 입니다.

다시 돌아와서 RDF는 리소스를 설명하기 위한 표준(W3C권장사항) 입니다.
리소스는 무엇인가요?? 라는 질문을 할 수 있는데 우리의 목적을 위해 식별할 수 있는 모든것으로 생각할 수 있습니다.

예를 들어보겠습니다. 이 예제는 사람과 조직을 설명하는 vCARDS의 RDF표현을 사용합니다.

리소스 John Smith는 타원으로 표시 되고 URI(Uniform Resource Identifier)로 식별 됩니다.
위에는 http://.../JohnSmith로 되어있네요!

리소스에는 속성이 있습니다. 위 그림에서는 John Smith의 Full Name이라는(vcard:FN) 속성을
하나 가지고 있습니다. 속성이름 또한 URI 입니다. URI는 다소 불편하기 때문에  : 앞부분을 네임스페이스라고 부르는데
네임스페이스의 이름으로 나타냅니다.(vcard)

리소스 속성에는 값이 있습니다. 이 경우 값은 리터럴(문자열)이며 리터럴은 직사각형으로 표시 됩니다.

Apache Jena는 이와 같은 RDF 그래프를 생성하고 조작할 수 있는 Java API입니다.
Jena에는 그래프, 리소스, 속성 및 리터럴을 나타내는 개체 클래스가 있습니다.
Resource, Property, Literal등의 인터페이스가 존재하며
Jena에서는 그래프를 모델이라고 하며 Model 인터페이스로 표현 됩니다.
아래 소스는 그래프! 즉, 모델을 하나 만들어서 리소스를 생성(personURI를 가지고)
속성을 추가 해주는 소스 입니다.

// some definitions
static String personURI    = "http://somewhere/JohnSmith";
static String fullName     = "John Smith";

// create an empty Model
Model model = ModelFactory.createDefaultModel();

// create the resource
Resource johnSmith = model.createResource(personURI);

// add the property
johnSmith.addProperty(VCARD.FN, fullName);

간결하게 아래와 같이 표현도 가능합니다.

Resource johnSmith =
      model.createResource(personURI)
           .addProperty(VCARD.FN, fullName);

아래와 같은 RDF가 있다면 기존 소스에서 어떻게 변경해야할까요?
기존 구조에서 vcard:N이라는 속성은 리소스로 사용을 했습니다. 리소스는 타원인데 타원에는 URI가 없습니다.
이는 빈 노드, Blank Node 입니다.

Blank Node는 URI로 식별되지 않는 리소스 입니다. 1차 논리에서 자격을 갖춘 변수처럼 동작합니다.
보통 관계를 나타내거나 임시적인 리소스를 나타낼때 중복되는 리소스를 나타낼때 사용 됩니다.

// some definitions
String personURI    = "http://somewhere/JohnSmith";
String givenName    = "John";
String familyName   = "Smith";
String fullName     = givenName + " " + familyName;

// create an empty Model
Model model = ModelFactory.createDefaultModel();

// create the resource
//   and add the properties cascading style
Resource johnSmith
  = model.createResource(personURI)
         .addProperty(VCARD.FN, fullName)
         .addProperty(VCARD.N,
                      model.createResource()
                           .addProperty(VCARD.Given, givenName)
                           .addProperty(VCARD.Family, familyName));

RDF 모델은 Statement라고 불립니다.
3가지 파트로 나눠지는데 SPO라고도 합니다.
S : Subject, P: Predicate, O: Object
 - Subject는 리소스를 나타내며
 - Predicate는 속성
 - Object는 리소스 또는 리터럴 입니다.

이 statement는 tripe이라고 불립니다.

// list the statements in the Model
StmtIterator iter = model.listStatements();

// print out the predicate, subject and object of each statement
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

    System.out.print(subject.toString());
    System.out.print(" " + predicate.toString() + " ");
    if (object instanceof Resource) {
       System.out.print(object.toString());
    } else {
        // object is a literal
        System.out.print(" \"" + object.toString() + "\"");
    }

    System.out.println(" .");
}

출력은 아래와 같습니다.
While문이 돌아가면서 
System.out.print(subject.toString()); 한번 찍고
System.out.print(" " + predicate.toString() + " "); 속성인 predicate를 찍고 
Resource인지 판단해보고 object를 찍고 마지막으로 . 을 찍습니다.

http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#N 413f6415-c3b0-4259-b74d-4bd6e757eb60 .
413f6415-c3b0-4259-b74d-4bd6e757eb60 http://www.w3.org/2001/vcard-rdf/3.0#Family  "Smith" .
413f6415-c3b0-4259-b74d-4bd6e757eb60 http://www.w3.org/2001/vcard-rdf/3.0#Given  "John" .
http://somewhere/JohnSmith http://www.w3.org/2001/vcard-rdf/3.0#FN  "John Smith" .

이제 RDF에 대해서 어떤 느낌인지 아셨을것 같습니다.
이제 Jena RDF API 관련 내용 입니다.

RDF 작성
jena에서는 RDF를 XML로 읽고 쓰는 방법이 있습니다.

// now write the model in XML form to a file
model.write(System.out);

아래와 같은 출력을 합니다.
<rdf:Description>는 리소스를 설명 합니다.
<vcard:FN>은 리소스의 속성을 설명 합니다.
vcard는 네임스페이스를 나타내며 RDF는 네임스페이스 접두사에 대한 URI참조와 FN을 연결하여 URI참조로 변환 합니다.
이는 http://www.w3.org/2001/vcard-rdf/3.0#FN URI참조를 제공 합니다. 
속성값은 문자 그대로 "John Smith" 입니다. 

<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/JohnSmith'>
    <vcard:FN>John Smith</vcard:FN>
    <vcard:N rdf:nodeID="A0"/>
  </rdf:Description>
  <rdf:Description rdf:nodeID="A0">
    <vcard:Given>John</vcard:Given>
    <vcard:Family>Smith</vcard:Family>
  </rdf:Description>
</rdf:RDF>

결론적으로  Apache jena는 RDF 모델 생성, 읽기, 쓰기를 할 수 있습니다.

model(그래프) 탐색
리소스의 URI가 있으면 모델에서 리소스 객체를 탐색할 수 있습니다.

// retrieve the John Smith vcard resource from the model
Resource vcard = model.getResource(johnSmithURI);

리소스 속성에 액세스를 하려면 Resource.getProperty(Property p) 메소스를 사용해 접근합니다.

// retrieve the value of the N property
Resource name = (Resource) vcard.getProperty(VCARD.N)
                                .getObject();

속성의 리터럴 값을 검색하려면 아래와 같습니다.

String fullName = vcard.getProperty(VCARD.FN)
                        .getString();

model  query
jena api는 제한된 쿼리 기본요소만 지원 합니다.
그래서 SPARQL을 사용합니다. SPARQL의 내용은 나중 포스팅에서 댜룹니다.
참고 : https://jena.apache.org/tutorials/sparql.html

jena에서는 아래와 같이 RDF를 조작할 수 있습니다.
deep하게는 들어가지 않고 조작할 수 있구나~정도만 알고 넘어가면 될 것 같습니다.
참고 : https://jena.apache.org/documentation/rdf/

Selector selector = new SimpleSelector(subject, predicate, object);
listStatements( new SimpleSelector( S, P, O ) )
// select all the resources with a VCARD.FN property
// whose value ends with "Smith"
StmtIterator iter = model.listStatements(
    new SimpleSelector(null, VCARD.FN, (RDFNode) null) {
        public boolean selects(Statement s)
            {return s.getString().endsWith("Smith");}
    });

다음으로는 Apache Fuseki 에 대해서 알아보도록 하겠습니다.

2024.01.18 - [OpenSource/Apache Jena] - 2. About Apache Fuseki

반응형

'OpenSource > Apache Jena' 카테고리의 다른 글

2. About Apache Fuseki  (0) 2024.01.18