RDF 자원

자원 기술 프레임워크라는 이름 자체에서 벌써 자원에 대해 기술해야 한다는 사실을 깨닫게 되지만, 도대체 이게 무엇인가?

자 원은 실제적이든(사람처럼) 직급이나 기회처럼 비실제적이든 무엇이든 될 수 있다. 중요한 것은 그것이 무엇이 되든 URI(Uniform Resource Identifier)를 사용하여 조회할 수 있도록 해야 한다는 점이다. URI의 한 타입은 인터넷에서 많이 보아왔던 URL(Uniform Resource Locator)인데, http://www.ibm.com 또는 mailto:ibmquestions@nicholaschase.com과 같은 것이다. 그러나 URI는 또한 더 일반적일 수 있다. 예를 들어 urn:backstopmedia 같은 것이 있는데, 이것은 URL이 아닌 URN(Uniform Resource Name)이다.

이는 URL로 웹 페이지나 이메일 주소(URL이 정보를 찾기 위해 제공하는 자원) 같은 자원을 식별할 수 있다는 것이고 URN을 통해서는 다른 자원을 식별할 수 있다는 뜻이다. 예를 들어 어떤 사람(미국 사람일 때)을 사회 보장 번호를 가리키는 URN인 ssn:078-05-1120으로 식별해야 한다고 하자. 물론 신원 도용의 시대에 그렇게 하고 싶지는 않을 것이다. 따라서 그 사람의 홈페이지(http://www.nicholaschase.com)나 내부적으로 일관성 있는 URL(http://www.example.com/employees/empto1138.html) 등을 이용하여 찾으려 할 것이다.

중요한 점은 URI 같은 것을 이용하여 자원을 식별할 수 있어야 한다는 점이다. 이에 따르는 폼은 별로 중요하지 않다.

RDF 특성

RDF를 사용하여 자원을 설명하기 위해서는 특성을 부여해야 한다. Listing 5에처럼 문장으로 특성 부여를 해 줄 수 있다.


Listing 5. 특성 부여하기
                     
Nick's blog has a name of Chaos Magnet
Nick's blog has a creator of Nicholas Chase

각 문장에는 제목(Nick의 블로그)과 술어(이름, 작성자), 객체(Chaos Magnet, Nicholas Chase)가 있다. 제목은 자원을, 술어는 특성을, 객체는 특성의 값을 각각 나타낸다. 그러므로 이 문장을 RDF 트리플처럼 바꾼다면 Listing 6에 보이는 것과 같은 결과를 얻을 것이다.


Listing 6. 나누기
                     
Nick's blog name Chaos Magnet .
Nick's blog creator Nicholas Chase .

물론 URI 같은 자원을 나타낸다면 Listing 7처럼 보일 것이다.


Listing 7. URI처럼 자원 나타내기
                     
http://www.chaosmagnet.com name Chaos Magnet .
http://www.chaosmagnet.com creator Nicholas Chase .

이것은 특성을 표현하는 평범한 문자열을 가지고 있으므로 여전히 실제 RDF 트리플이 아니다. 문제는 특성도 자원처럼 URI 형태로 나타나야 한다는 것이다.







URI 레퍼런스

사실 특성은 URIref(URI reference)로 나타낸다. URIref는 특성의 바탕, 실제로는 특성이 속한 이름공간으로 구성되어 있다. 그 뒤에는 단편(fragment)이 따라온다.

예를 들어 Listing 7의 예제에서는 creator 특성을 인용했다. 실제로는 creator 특성은 더블린 코어 이름공간에 의해 정의되었므로 완전한 URIref는 Listing 8처럼 나타날 것이다.


Listing 8. creator을 위한 완전한 URIref
                     
http://purl.org/dc/elements/1.1/#creator

만약 독자들이 웹 개발자라면 구문 끝부분에 # 표시로 시작되는 단편이 낯설지 않을 것이다. 이는 브라우저를 페이지의 특정 장소로 보낼 때 사용하는 구문과 같은 것이다. Listing 9를 보자.


Listing 9. 단편을 포함하는 URL
                     
https://www6.software.ibm.com/developerworks/education/ws-understand-
web-services3/#N1014F

페이지의 특정 장소를 만들어주기 위해서는 Listing 10처럼 앵커 태그를 만들어주면 된다.


Listing 10. 앵커 태그 만들기
                     
<a name="N1014F">:</a>

HTML의 XML 버전인 XHTML의 출현으로 이는 Listing 11처럼 바뀐다.


Listing 11. XHTML 앵커 태그
                     
<a id="N1014F" />

그러므로 요소를 인용하는 단편은 # 표시이고 ID 속성 값이다(XPointer를 아는 사람은 다 아는 이야기다). 이후 rdf:ID 속성을 사용하여 자원을 만들면 이를 다시 보게 되겠지만, 지금 URIref가 URL이라는 관점에서 보면 이는 첨부된 단편일 것이다.

이는 또한 RDF 속성을 지정하는 유일한 방법이다. 그러므로 문장은 Listing 12처럼 된다.


Listing 12. URIref로서 특성
                     
http://www.chaosmagnet.com http://example.com#name Chaos Magnet .
http://www.chaosmagnet.com http://purl.org/dc/elements/1.1/#creator
Nicholas Chase .

이를 축약하고 싶을 때는 실제 이름공간을 나타내는 접두사를 부여해야 한다. 이렇게 하면 Listing 13처럼 문장을 줄일 수 있다.


Listing 13. 문장 줄이기
                     
http://www.chaosmagnet.com ex:name Chaos Magnet .
http://www.chaosmagnet.com dc:creator Nicholas Chase .

이제 실제 RDF 폼에 많이 가까워졌지만 아직 완전하지는 않다.







특성 값

대 체로 지금까지 보아온 특성들은 단순한 문자열 값을 가지고 있지만 실제 상황에서는 이런 경우는 드물다. 왜 그런지 이해하기 위해서는 문자 그대로 받아들일 필요가 있다. 내가 "Nick의 블로그는 'Nicholas Chase'가 만들었다"라고 한다면 이는 말이 안 되는 문장이다. 문자열("Nicholas Chase")이 내 블로그를 만들지는 않았다(그렇게 보일 때도 있지만). 내가 하고 싶은 말은 사실 "'Nick의 블로그'라고 알려진 자원은 'Nicholas Chase'라고 알려진 자원에 의해 만들어졌다"이다.

그러므로 실제 트리플은 Listing 14와 비슷한 모양일 것이다.


Listing 14. 트리플에 더 가까워지기
                     
http://www.chaosmagnet.com dc:creator http://www.nicholaschase.com

이를 RDF 그래프로 나타낼 수 있다.







RDF 그래프

이 모든 정보를 나타내는 한 방법은 RDF 그래프를 사용하는 방법이다. 이 그래프에서 모든 것이 맞춰지는 것을 볼 수 있다. 예를 들어 그림 1을 보자.


그림 1. RDF 그래프
RDF 그래프

타원형의 노드는 자원을 나타내고 그 사이의 화살표들은 특성을 나타낸다. 자원인 특성 값은 타원형처럼 보이고 문자 값은 박스로 보인다.







RDF 표기법

지금까지 RDF 정보를 슬쩍 본 적은 있겠지만 형식적인 모양은 본 적이 없을 것이다. Listing 15처럼 자원 URIref가 완전한 형태로 작성된 트리플을 사용할 수 있다.


Listing 15. 완전한 URIref 트리플
                     
<http://www.chaosmagnet.com> <http://example.com#name> Chaos Magnet .
<http://www.chaosmagnet.com>
<http://purl.org/dc/elements/1.1/#creator>
<http://www.nicholaschase.com> .

(공간 제약이 있긴 했지만 각 트리플은 대체로 한 줄에 작성된다.)

Listing 16처럼 이름공간을 접두사로 바꿔 줄여 표현할 수도 있다.


Listing 16. 축약된 표기법
                     
@prefix ex: <http://example.com> .
@prefix dc: <http://purl.org/dc/elements/1.1/#creator> .
<http://www.chaosmagnet.com> ex:name "Chaos Magnet" .
<http://www.chaosmagnet.com> dc:creator
<http://www.nicholaschase.com> .

괄호 안에는 완전한 URIref만 있었다는 점에 주목하자. 하지만 RDF를 볼 수 있는 가장 흔한 방법은 XML일 것이다. 예를 들어 Listing 17에서 볼 수 있는 것처럼 관계를 나타낼 수 있다.


Listing 17. XML 표기법
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex = "http://example.com#"
xmlns:dc="http://purl.org/dc/elements/1.1/#">

<rdf:Description rdf:about="http://www.chaosmagnet.com">
<ex:name>Chaos Magnet</ex:name>
<dc:creator rdf:resource="http://www.nicholaschase.com" />
</rdf:Description>
</rdf:RDF>

XML로 RDF를 나타내는 더 많은 방법은 다음 섹션에서 다루겠다.


RDF/XML

XML만이 RDF를 나타내는 유일한 방법은 아니다. 특히 자원과 특성 간의 관계를 보여주고자 할 때는 가장 좋은 방법도 아니다. 하지만 XML은 가장 인기 있는 방법이기도 하고 시맨틱 웹에 있어서는 가장 편리한 방법이기도 하다. 더 자세히 들여다보자.

존재하는 자원 기술하기

가 장 일반적인 RDF는 RSS 피드의 한 부분이나 전체처럼 이미 존재하는 자원을 기술하는 것이다. 이런 경우, 일반적으로 RDF는 다른 XML 문서에 포함되어 있거나 XML 이름공간을 사용하면서 구분된다. 하지만 단순함을 위해 RDF만 따로 놓고 보도록 하자.

Listing 18처럼 테크노라티의 "movies" 태그에 보낸 질의에 의해 반환된 데이터를 기술하는 간단한 문서로 시작해보자.


Listing 18. 존재하는 자원 기술하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate>Sun, 30 Jul 2006 11:38:42 PST</tapi:PubDate>
<tapi:Inboundlinks>321580</tapi:Inboundlinks>

</rdf:Description>
</rdf:RDF>

여기 rdf:about 속성에 기술된 자원을 위한 특성을 가지고 있는 Description이 들어있는 rdf:RDF 요소가 있다. 이 경우 특성은 http://www.technorati.com/tag#라는 이름공간에서 비롯되었다. 만약 이름공간을 확장하면 Title이라는 특성을 볼 수 있는데, 이는 실제 http://www.technorati.com/tag#Title 특성이다.

이 때 자원에 원하는 만큼 많은 특성을 추가할 수 있다.

하 지만 이것이 XML로 RDF를 나타내는 유일한 방법이 아님을 또한 주목하자. 다른 문서에 RDF를 포함하고자 하는 경우가 종종 있기 때문에 원래 정보를 훼손하지 않으려고 그렇게 하고 싶을 것이다. 하지만 여기서 데이터를 보여주는 방식은 만약 브라우저에 정보를 추가할 경우 요소의 텍스트 내용이 페이지에 보이는 것이다. 이해못한 태그 내용을 단순히 보여주는 브라우저의 기본 동작일 뿐이다.

이를 방지하기 위해 정보를 요소 대신 속성에 놓는 방식의 다른 메서드를 사용할 수 있다. Listing 19를 보자.


Listing 19. 요소 안에 있는 RDF 데이터
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies"
tapi:Title="[Technorati] Tag results for Movies"
tapi:PubDate="Sun, 30 Jul 2006 11:38:42 PST"
tapi:Inboundlinks="321580" />

</rdf:RDF>

정보는 같지만 이제는 요소 내용이 아니라 속성 값에 놓이므로 브라우저에서 보이지 않는다.







데이터 타입 지정하기

때때로 특정 데이터가 어떻게 다뤄지는지 명확히 하고 싶을 때가 있다. 따라서 의도된 데이터 타입을 지정할 수 있다면 도움이 될 것이다. Listing 20을 예로 보자.


Listing 20. 데이터 타입 지정하기
                    
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>

</rdf:Description>
</rdf:RDF>

이 경우, XML 스키마 명세에서 정의한 것처럼 날짜 타입이어야 하는 PubDate와 정수 타입이어야 하는 Inboundlinks 요소를 각각 지정한다. 이것이 URIref의 이름공간을 기반으로 하는 이 타입의 XML 스키마 버전임을 알 수 있을 것이다. 사실 XML 스키마 데이터 타입을 사용해야만 한다는 법은 없지만, 사용하기 편리하고 XML 애플리케이션이 이미 그것을 이해하고 있기 때문에 사용하지 않을 이유가 없다.

또한 Listing 21처럼 N3 표기법으로도 타입을 나타낼 수 있다.


Listing 21. N3 표기법에서 데이터 타입 지정하기
                     
<http://www.technorati.com/tag/Movies>
<http://www.technorati.com/tag#Inboundlinks>
"321580"^^http://www.w3.org/2001/XMLSchema#integer .

RDF 자체가 이러한 데이터 타입을 강화하거나 검증하지 않는다는 것에 주목하자. 날짜에 문자열을, 또는 URL에 숫자를 입력할 수도 있다. RDF는 단순히 정보를 표기하는 방법을 제공할 뿐이고 RDF 애플리케이션은 데이터가 일치하는지 확인할 뿐이다.







존재하는 자원 참조하기

존재하는 자원을 기술하는 것뿐만 아니라 이를 사용하여 다른 자원을 기술할 때도 있다. 예를 들어, Listing 22처럼 이미지 특성을 기술하거나 추가하는 피드를 가질 수 있다.


Listing 22. 자원을 특성 값처럼 참조하기
                    
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>

<tapi:Image rdf:resource
"http://static.technorati.com/pix/logos/logo_sm.gif"/>


</rdf:Description>
</rdf:RDF>

값을 rdf:resource로 지정하고 이를 실제 특성 값인 URI로 사용했다는 것에 주목하자. 하지만 어떤 경우에는 현재 이름공간 밖에서 정의되지 않은 자원을 참조하고자 할 때도 있다. 예를 들어 만약 참조하고자 하는 이미지가 단일 URL에서 참조할 수 있는 파일이 아니라 특성의 컬렉션이면 어떻게 해야 하는가? 그러므로 이 자원의 정의를 짚어주어야 할 필요가 있다.

이를 위해 Listing 23처럼 두 번째 Description을 만들고 nodeID를 지정한다.


Listing 23. 익명 노드 사용하기
                    
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:nodeID="image1"/>

</rdf:Description>

<rdf:Description rdf:nodeID="image1">
<tapi:Url>
http://static.technorati.com/pix/logos/logo_sm.gif
</tapi:Url>
<tapi:Title>Technorati logo</tapi:Title>
<tapi:Link>http://www.technorati.com</tapi:Link>
</rdf:Description>

</rdf:RDF>

두 번째 Description 요소를 만들고 이를 nodeID로 지정한다는 것에 주목하자. 이를 통해 tapi:Image 특성으로부터 참조할 수 있는 자원을 만들 수 있도록 하였다. 이것을 nodeID라 부르는데, 그 이유는 만약 데이터를 위해 RDF 그래프를 그릴 경우 앞에서 본 그림 1의 image1 노드는 자체 특성을 가지는 빈 타원형 노드일 것이기 때문이다.







새로운 자원 만들기

nodeID를 사용하여 이름공간과 문서 안의 내용 안에서만 이 노드를 참조하는 방법을 만들어보자. 하지만 가끔 다른 문서나 이름공간 등에서 참조할 수 있는 자원을 만들고 싶을 것이다.

Listing 24처럼 rdf:ID 속성을 사용하여 만들 수 있다.


Listing 24. 새로운 자원 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>

</rdf:Description>

<rdf:Description rdf:ID="image1">
<tapi:Url>
http://static.technorati.com/pix/logos/logo_sm.gif
</tapi:Url>
<tapi:Title>Technorati logo</tapi:Title>
<tapi:Link>http://www.technorati.com</tapi:Link>
</rdf:Description>

</rdf:RDF>

XML 문서 안에서 ID 속성으로 요소를 식별함으로써 단편을 만들고 이를 어떤 것에 참조할 것인지에 대해 언급한 것을 기억하는가? 이제 어떻게 작동하는지 보자. 새로운 자원을 만들고 여기에 image1이라는 ID를 부여하면 #image1이라는 상대 URI로 이 ID를 참조할 수 있다.

여 기서 상대 URI라고 했음을 주목하자. 이 자원의 실제 완전한 URI는 단편이 따라오는 문서의 기본 URI다. 예를 들어, RDF 검증기로 이 문서를 검사했다면 http://www.w3.org/RDF/Validator/run/1154295344338#image1라는 URI를 얻었을 것이다.

물론 전혀 예측 불가능한 것은 아니므로 Listing 25처럼 xml:base 속성을 사용하여 기본 URI을 직접 지정하는 것이 더 낫다.


Listing 25. 기본 URI 지정하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">

<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>

</rdf:Description>

<rdf:Description rdf:ID="image1">
<tapi:Url>
http://static.technorati.com/pix/logos/logo_sm.gif
</tapi:Url>
<tapi:Title>Technorati logo</tapi:Title>
<tapi:Link>http://www.technorati.com</tapi:Link>

</rdf:Description>

</rdf:RDF>

이제 문서가 어디에 있든 이미지 자원의 완전한 URI는 http://www.technorati.com/tag#image임을 확신할 수 있다. 이 일관성 덕분에 어떤 문서나 이름 공간이든 자원을 참조할 수 있다.

rdf:ID 속성 값은 이름공간에서 유일해야만 하고, 요소에서 특정 자원을 정의해야만 한다는 것을 기억하자.







다수의 기술(description) 사용하기

지금까지 단일 Description 요소에서만 자원을 만들거나 기술하였지만 꼭 그럴 필요는 없다. 최초 피드의 기술을 분리하여 각기 다른 Description 요소에 보낼 수 있다. Listing 26을 보자.


Listing 26. 다수의 Description 요소로 자원 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">
<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:Image rdf:resource="#image1"/>
</rdf:Description>

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
</rdf:Description>

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
</rdf:Description>

<rdf:Description rdf:ID="image1">
<tapi:Url>
http://static.technorati.com/pix/logos/logo_sm.gif
</tapi:Url>
<tapi:Title>Technorati logo</tapi:Title>
<tapi:Link>http://www.technorati.com</tapi:Link>
</rdf:Description>

</rdf:RDF>

이 기술 형태에서 특히 재미있는 것은 Description 요소가 어디든 놓일 수 있다는 것이다. 이제 정확하기만 하다면 온 세상의 정보를 포함하는 자원을 만들 수 있다.







명시된 타입

온 톨로지를 만들기 시작하면 자원의 타입을 만들기 시작해야 한다. 이를테면 Service 타입, Price 타입, Owner 타입 등과 같은 자원 타입을 만들어 다른 서비스로부터 얻어진 정보를 분류할 수 있다. 이처럼 정보를 분류하는 것은 데이터의 "타입"을 설정하는 것이다. Listing 27을 보자.


Listing 27. 데이터 타입 설정하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#">

<rdf:Description rdf:about="http://www.technorati.com/tag/Movies">
<rdf:type rdf:resource="http://www.example.com/mashup/Feed" />
<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>

</rdf:Description>
...

여기서는 그저 임의의 타입일 뿐이지만, RDF 스키마를 다룰 때 타입을 정의하는 방법을 간단히 볼 수 있을 것이다.







대안적인 폼: 요소 이름으로서 타입

특정 타입의 데이터를 결정했다면 이를 rdf:type 속성을 설정하는 것보다 더 깔끔한 방법으로 표현할 수도 있다. 대신 Listing 28처럼 Description 요소의 공간에 타입의 이름을 사용할 수 있다.


Listing 28. 요소 이름처럼 타입 이름 사용하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#"
xmlns:mashup="http://www.example.com/mashup/">

<mashup:Feed
rdf:about="http://www.technorati.com/tag/Movies">
<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>
</mashup:Feed>

<rdf:Description rdf:ID="image1">
...
</rdf:Description>

</rdf:RDF>

이 코드는 mashup: 접두사를 정의하여 http://www.example.com/mashup/라는 이름 공간을 나타낸다. 결국 앞에서 본 예제처럼 http://www.example.com/mashup/Feed로 데이터 타입을 정한 것이다.

OWL과 적어도 RDF 스키마에 대해 언급하기 시작하면 이런 데이터 타입을 표현하는 형식은 중요해지고 일반적이 된다.







백(bag), 시퀀스, 대안

지 금까지 단일하고 구별되는 값을 가지는 특성을 다뤄왔지만 실제 상황에서 다룰 특성은 늘 그렇지 않다. 대체로 적어도 하나 또는 두 가지 일 대 다수의 관계를 가지고 있기 때문이다. 예를 들어 피드에 정보 자체가 들어있을 수 있지만 또한 이와 관련된 수십 개의 아이템 엔티티가 들어있을 수도 있다.

RDF에서는 몇 가지 다른 방법으로 이런 관계를 표현할 수 있다. 가장 단순한 방법은 Listing 29처럼 Bag을 이용하는 것이다.


Listing 29. 하나 대 다수의 관계를 Bag으로서 표현하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#"
xmlns:mashup="http://www.example.com/mashup/">

<mashup:Feed rdf:about="http://www.technorati.com/tag/Movies">
<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate
rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks
rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>

<tapi:Items>
<rdf:Bag>
<rdf:li rdf:resource="http://www.robotjohnny.com/2006/07/30/haiku-
review-lady-in-the-water/"/>
<rdf:li
rdf:resource="http://riesje.livejournal.com/5359.html"/>
<rdf:li
rdf:resource="http://www.vanguardreport.com/phpnuke/index.php"/>
</rdf:Bag>
</tapi:Items>


</mashup:Feed>
...

내부적으로 RDF는 백 안의 각각의 아이템을 세고 있지만 또한 편리성을 위해 rdf:li 요소를 제공한다(HTML 목록 아이템과 맞춰).

rdf:Bag은 이름 그대로다. 이는 많은 아이템들이 특정한 순서 없이 모여있는 것을 말한다. 백 안의 모든 아이템은 똑같이 중요하다.

물론 언제나 그렇진 않다. 즉, Items가 특별히 날짜 순으로 정렬된다면 순서는 중요해진다. 이를 표현하기 위해 Listing 30처럼 시퀀스를 만들 수 있다.


Listing 30. 시퀀스 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:tapi="http://www.technorati.com/tag#"
xml:base="http://www.technorati.com/tag#"
xmlns:mashup="http://www.example.com/mashup/">

<mashup:Feed rdf:about="http://www.technorati.com/tag/Movies">
<tapi:Title>[Technorati] Tag results for Movies</tapi:Title>
<tapi:PubDate rdf:datatype="http://www.w3.org/2001/XMLSchema#date">
Sun, 30 Jul 2006 11:38:42 PST
</tapi:PubDate>
<tapi:Inboundlinks rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">
321580
</tapi:Inboundlinks>
<tapi:Image rdf:resource="#image1"/>

<tapi:Items>
<rdf:Seq>
<rdf:li rdf:resource="http://www.robotjohnny.com/2006/07/30/haiku-
review-lady-in-the-water/"/>
<rdf:li
rdf:resource="http://riesje.livejournal.com/5359.html"/>
<rdf:li
rdf:resource="http://www.vanguardreport.com/phpnuke/index.php"/>
</rdf:Seq>
</tapi:Items>


</mashup:Feed>
...

기능적으로 rdf:Seqrdf:Bag과 같지만 사용할 때는 순서가 중요함을 암시한다. RDF 자체가 이 구별을 가능케 하진 않는다. RDF는 합의된 방법으로 정보를 표현할 뿐이고, 애플리케이션 자체는 보존된 순서를 강화할 뿐이다.

하나 대 다수 관계에 있어 또 하나 다룰 것은 유일한 그룹이 적용된는 상황이다. 이 경우, Listing 31처럼 애플리케이션이 보여주려고 선택한 특정 아이템의 세트를 가지고 있어야 한다.


Listing 31. rdf:Alt 사용하기
                     
...
<rdf:li rdf:resource="http://www.vanguardreport.com/phpnuke/index.php"/>
</rdf:Seq>
</tapi:Items>


<mashup:FeaturedItem>
<rdf:Alt>
<rdf:li rdf:resource="http://www.robotjohnny.com/2006/07/30/haiku-
review-lady-in-the-water/"/>
<rdf:li
rdf:resource="http://riesje.livejournal.com/5359.html"/>
<rdf:li
rdf:resource="http://www.vanguardreport.com/phpnuke/index.php"/>
</rdf:Alt>
</mashup:FeaturedItem>


</mashup:Feed>
...

구문은 rdf:Bag이나 rdf:Alt나 같지만 애플리케이션의 경우(애플리케이션의 책임이라는 것을 기억하라!) 단 하나의 아이템을 포함하는 것을 선택해야 한다.







컬렉션

이전에 다수의 rdf:Description 요소를 사용하여 단일 자원을 기술할 수 있는 방법에 대해 언급한 것을 기억하는가? 그 경우, 모든 정보는 단일 자원 안에 모여 있어야 한다. 즉, 만약 Bag(또는 Seq나 Alt)를 정의한다고 할 때 두 번째 rdf:Description은 여기에 아이템을 추가할 수 있다. 이를 방지하기 위해 Collection이라는 그룹을 정의할 수 있다. Listing 32를 보자.


Listing 32. Collection 사용하기
                     
...
</rdf:Seq>
</tapi:Items>


<mashup:FeaturedItems rdf:parseType="Collection">
<rdf:Description rdf:about="http://www.robotjohnny.com/2006/07/30/haiku-
review-lady-in-the-water/"/>
<rdf:Description rdf:about=
"http://riesje.livejournal.com/5359.html"/>
<rdf:Description rdf:about=
"http://www.vanguardreport.com/phpnuke/index.php"/>
</mashup:FeaturedItems>


</mashup:Feed>
...

이 경우 Collection에 속한 특정 자원을 정의하고 rdf:parseType 속성이라고 표시한다.

RDF는 두 가지 다른 parseType 값을 정의한다. 이 때, 이전에 NodeID를 사용했던 것처럼 Resource 값을 사용하여 빈 노드를 만들 수 있고, Literal 값을 사용하여 임의의 XML 정보를 포함하는 요소를 만들 수 있다. 예를 들어, Summary에 XHTML을 포함하여 보여줄 수 있거나 이 연재의 Part 1처럼(참고자료 참조) XML 템플릿을 포함하여 보여줄 수 있다.



RDF 스키마

RDF는 자원에 대한 정보가 어떻게 지정되는지를 기술하지만 정보 자체는 아무런 의미가 없다. 단지 클래스와 하위클래스 같은 아이템 타입과 그 관계를 정의하기 위해 용어에 몇 가지를 더 추가할 필요가 있다. 이 때 추가하는 것은 RDF 스키마로 요약된다. RDF 스키마는 자체의 이름공간과 미리 지정된 요소와 속성을 가지고 있다. 이 절에서는 클래스와 객체, 그리고 이들의 관계를 만들 때 무엇이 필요한지 다루도록 하겠다.

클래스 만들기

용 어를 정의하는 첫 번째 단계는 클래스를 만드는 것이다. 객체지향 언어의 클래스처럼 RDFs 클래스도 각각 객체를 만들 때 템플릿 타입을 제공하거나 RDF 용어(parlance)에서 호출된다. 일단 Listing 33처럼 서비스와 관련된 클래스를 만드는 것으로 시작하자.


Listing 33. 기본 클래스
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.example.com/mashup/">

<rdf:Description rdf:ID="Service">
<rdf:type rdf:resource="http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="SOAPService">
<rdf:type rdf:resource="http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="RESTService">
<rdf:type rdf:resource="http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="RSSFeed">
<rdf:type rdf:resource="http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

</rdf:RDF>

여기선 클래스를 네 개 만들었다. http://www.w3.org/2000/01/rdf-schema#Class 타입으로 표시되었기 때문에 이것이 클래스라는 것을 알 수 있다(그러므로 rdf:Description 대신에 rdfs:Class를 사용할 수 있다).




위로


하위클래스 만들기

클래스를 정의하고 나면 rdfs:subClassOf 특성으로 관계를 만들 수 있다. Listing 34를 보자.


Listing 34. 하위클래스 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.example.com/mashup/">

<rdf:Description rdf:ID="Service">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="SOAPService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RESTService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RSSFeed">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#RESTService" />
</rdf:Description>

</rdf:RDF>

여기서 Service의 하위클래스로 SOAPServiceRESTService를, RESTService의 하위클래스로 RSSFeed를 정의하였다. 이 말은 만약 RSSFeed로 하나를 정의하면 이것이 또한 RESTServiceService라는 것을 안다는 말이다.




위로


인스턴스 만들기

이제 클래스를 갖게 되었으니 객체지향 언어의 객체와 같은 개체를 어떻게 만들 것인가?

이전에 자원을 만들었던 것과 같은 방법으로 인스턴스를 만들되, Listing 35처럼 이미 만든 클래스를 기반으로 하는 타입을 지정한다는 것이 다르다.


Listing 35. 개체 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:mashup="http://www.example.com/mashup/"
xml:base="http://www.example.com/mashup/services">


<rdf:Description rdf:ID="Google">
<rdf:type rdf:resource=
"http://www.example.com/mashup/#SOAPService"/>
</rdf:Description>

<rdf:Description rdf:ID="Amazon">
<rdf:type rdf:resource=
"http://www.example.com/mashup/#RESTService"/>
<rdf:type rdf:resource=
"http://www.example.com/mashup/#SOAPService"/>
</rdf:Description>

</rdf:RDF>

이 때 이름공간을 적어놓아야 한다. definitions에 사용한 기본 이름공간과 맞는 mashup: 접두사와 기본을 위한 새로운 이름공간을 정의했다.

구 글과 아마존이라는 두 개의 개체를 만들고 이들의 타입을 부여했다. REST와 SOAP 요청을 받아들이는 아마존 서비스는 실제 두 가지 타입을 가지고 있음에 주목하라. 이는 각각의 클래스에 지정된 특성을 갖고 있다는 말이다. 속성 이름처럼 타입 이름을 사용하는 대안적인 포맷을 사용하여 이 코드를 단순화할 수 있다. Listing 36을 살펴보자.


Listing 36. 프레젠테이션 단순화하기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:mashup="http://www.example.com/mashup/"
xml:base="http://www.example.com/mashup/services">

<mashup:SOAPService rdf:ID="Google">
</mashup:SOAPService>

<mashup:RESTService rdf:ID="Amazon">
<rdf:type rdf:resource=
"http://www.example.com/mashup/#SOAPService"/>
</mashup:RESTService

</rdf:RDF>

여전히 다양한 클래스를 지정할 수 있지만 두 번째 클래스는 명시적으로 나타나야 한다는 것을 기억하라. 이제 클래스에 특성을 추가하는 방법을 살펴보자.




위로


특성 만들기

객체지향 언어에서는 클래스의 컨텍스트에 특성을 만들면 된다. 하지만 RDFs에서는 특성 내에서 특성을 만들고 클래스에 이를 부여해야 한다. Listing 37을 보자.


Listing 37. 특성 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.example.com/mashup/">

<rdf:Description rdf:ID="Service">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="SOAPService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RESTService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RSSFeed">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#RESTService" />
</rdf:Description>

<rdf:Property rdf:ID="baseUrl">
<rdfs:domain rdf:resource="#RESTService" />
<rdfs:range rdf:resource=
"http://www.w3.org/2001/XMLSchema#anyURI"/>
</rdf:Property>

<rdf:Property rdf:ID="endpoint">
<rdfs:domain rdf:resource="#SOAPService" />
<rdfs:range rdf:resource=
"http://www.w3.org/2001/XMLSchema#anyURI"/>
</rdf:Property>


</rdf:RDF>

여기서 baseUrlendpoint라는 두 개의 특성을 만들고 이들의 도메인과 범위를 지정하였다. 도메인은 특성이 나타날 수 있는 자원 타입이고 범위는 이를 담을 수 있는 데이터 타입이다.

도 메인은 추론에 사용할 수 있기 때문에 생각보다 중요하다. 예를 들어, endpoint 특성은 SOAPservice에만 보일 수 있기 때문에 만약 개체가 endpoint를 갖고 있다면 특별히 표시되지 않더라도 이것이 SOAPService라는 것을 알 수 있다. 이후 온톨로지를 살펴보고 서비스를 부여하고 특정 클래스에 그 데이터를 보내 결정을 할 때 추론 능력이 매우 중요해진다.




위로


하위특성 만들기

하위클래스를 만들어 클래스를 특화하는 것과 같은 방법으로 하위특성을 만들어 특성을 특화할 수 있다. 예로 Listing 38을 보자.


Listing 38. 하위특성 만들기
                     
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.example.com/mashup/">

<rdf:Description rdf:ID="Service">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
</rdf:Description>

<rdf:Description rdf:ID="SOAPService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RESTService">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#Service" />
</rdf:Description>

<rdf:Description rdf:ID="RSSFeed">
<rdf:type rdf:resource=
"http://www.w3.org/2000/01/rdf-schema#Class"/>
<rdfs:subClassOf rdf:resource="#RESTService" />
</rdf:Description>

<rdf:Property rdf:ID="accessUrl">
<rdfs:domain rdf:resource="#Service" />
</rdf:Property>


<rdf:Property rdf:ID="baseUrl">
<rdfs:subPropertyOf rdf:resource="#accessUrl" />
<rdfs:domain rdf:resource="#RESTService" />
<rdfs:range rdf:resource=
"http://www.w3.org/2001/XMLSchema#anyURI"/>
</rdf:Property>

<rdf:Property rdf:ID="endpoint">
<rdfs:subPropertyOf rdf:resource="#accessUrl" />
<rdfs:domain rdf:resource="#SOAPService" />
<rdfs:range rdf:resource=
"http://www.w3.org/2001/XMLSchema#anyURI"/>
</rdf:Property>

</rdf:RDF>

Listing 38에서 accessUrl이라는 전반적인 특성을 만들고 baseUrl과 endpoint 특성을 정의하여 이 특성을 특화하였다. 이는 자원으로 accessUrl을 만든다면 어떤 특성을 부여하든 이들 특성은 또한 하위특성에 적용된다는 것을 말한다.



출처 : http://www.ibm.com/developerworks/kr/library/tutorial/x-ultimashup3/section3.html

'Technology > Programming' 카테고리의 다른 글

HTML / HTML5는 모바일 인터넷 활성화의 촉매  (0) 2010.03.29
JSP / JSP 한글처리  (0) 2010.03.15
Tools / SVN 용어 설명  (0) 2010.02.23
HTML / HTML5 Tags  (0) 2010.02.07
JSP / JSP 문법 정리(자주 쓰는 것들)  (0) 2010.02.02

+ Recent posts