달력

22025  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28


 

 

메탈리카 또 하나의 매력은 곡의 가사다.

종교적 또는 철학적인 냄새가 강하게 풍기는 가사가

메탈리카를 다른 그룹과 차별화하게 한다. (큭~ Fade to black은 정말 끝장이지..)

이 곡 Creeping Death는 메탈리카 곡 중 가장 열나게 흔들어 제낄 수 있는

곡으로 사실 나도 리듬만 의식했지 가사는 염두해 두지 않았으나,

펀 글보고 가사보니 오호~란 생각이 또 드는군. 출처가 성경이라니..

긴 글이지만 펀 글을 그대로 싣겠습니다.

펀 글의 출처는 Daum에 있는 악숭카페의 Kyle Park님입니다. (추가했습니다)

==================================================================

 

Creeping Death...

서서히 다가오는 죽음 이라는뜻입니다.

 

가사를 대충 보자면

기독교 성경의 유월절 이야기인데

 

이집트의 왕자를 본 분들이라면 기억날겁니다.

 

대충 간략하자면

 

모세라는 사람이 히브리인들을 이집트의 왕 파라오의 손에서 벗어나기위해

하나님께 기도했는데

하나님께서 이집트에 10가지 재앙을 내리시겟다고 하셧습니다.

 

그 재앙들은

물이 피로 변하고

곤충들이 곡식을 갉아먹고

점염병이 돌고

불우박이 떨어지고

3일간 암흑이 내리고

개구리가 사방을 둘러싸는

이집트에 저주가 이루어지다가

마지막 재앙이 내렸는데

그 마지막 10번째 재앙이 바로

 

"죽음의 사자"였습니다.

 

죽음의 사자는 하늘에서 하나님이 보낸 사자인데

새끼양의 피를 문앞에 바르면 그 죽음의 사자가 그 집은 지나쳐 간다고합니다.

(이집트 왕자에서 보면 하얀 영혼같은게 떠다니죠? 그게 죽음의 사자입니다.)

죽음의 사자는 모든 이집트 백성의 장남들을 죽였습니다.

파라오의 아들 마저도 죽었죠.

 

이 곡은 10번째 즉 마지막 재앙인

죽음의 사자가 파라오의 아들을 죽이러 간다는 내용입니다.

(파라오의 아들에게 서서히 죽음이 다가간다는 예기겟죠.)

 

역시 헷필드 아저씨 센스 지존이십니다.-_-b

어떻게 이런 성경이야기까지 헤비메탈 가사로 바꿔 쓸 생각을 하셧을지....

-------------------------------------------------------------------

이 라이브에 대해서 설명하자면

80년도 말에 모스크바에서 평화를 기념하는 콘서트가 열렸는데

이날에는 몇몇 대단한 밴드들이 나오는 날이였답니다.

그중 메탈리카가 한편이였는데

 

관중이 33만명....

 

마을하나를 매꿀수있을 수의 사람이 메탈리카 콘서트를 관람했답니다.

아마 이 콘서트가 메탈리카 콘서트중 가장 큰 규모였던걸로 기억합니다.

---------------------------------------------------------

설명쓰기 참힘드네;;;

마지막으로 자필 가사입니다.

 

[Lyric]

Creeping Death (Hetfield,Ulrich,Burton,Hammett)

Slaves

노예들
Hebrews born to serve, to the pharaoh

히브리 인들은 파라오를 섬기기 위해서 태어났어
Heed

주의
To his every word, live in fear

파라오의 명령은 사람들을 공포에 몰아넣었지
Faith

믿음
Of the unknown one, the deliverer

알려지지 않은 사자(詞者)
Wait

기다려라
Something must be done, four hundred years

400년 후에 이루어질 것이다

So let it be written

그러니 이것을 기록하라
So let it be done

그리고 행하여라
I'm sent here by the chosen one

나는 선택받아 이곳에 왔느니라
So let it be written

그러니 이것을 기록하라

So let it be done

그리고 행하여라
To kill the first born pharaoh son

파라오의 장남에게 죽음을...
I'm creeping death

나는 서서히 다가오는 죽음이다.....

Now

지금
Let my people go, land of goshen

내 백성들을 고센으로 보내라
Go

가거라
I will be with thee, bush of fire

내가 불기둥이 되어 너희와 함께 하리라
Blood


Running red and strong, down the nil

붉고 짖은 피가 나일강을 적시리라
Plague

점염병
Darkness three days long, hail to fire

암흑이 3일간 지속되고, 불우박이 내릴것이다.

So let it be written

그러니 이것을 기록하라
So let it be done

그리고 행하여라
I'm sent here by the chosen one

나는 선택받아 이곳에 왔느니라
So let it be written

그러니 이것을 기록하라

So let it be done

그리고 행하여라
To kill the first born pharaoh son

파라오의 장남에게 죽음을...
I'm creeping death

나는 서서히 다가오는 죽음이다.....

Die by my hand

죽어라 나의 손에
I creep across the land

대지를 가로지르며 다가간다
Killing first born man

장남을 죽이러
Die by my hand

죽어라 나의 손에
I creep across the land

대지를 가로지르며 다가간다
Killing first born man

장남을 죽이러

I

나는
Rule the midnight air the destroyer

새벽의 공기를 지배하는 파괴자다
Born

탄생
I shall soon be there, deadly mass

내가 곳 그곳으로 가리라, 학살
I

내가
Creep the steps and flood final darkness

계단을 넘어 바닥에 닿을때 마지막 암흑이 끝나리라.
Blood


Lambs blood painted door, I shall pass

문에 새끼 양의 피가 칠해져 있는 집은 해치지 않으리...

So let it be written

그러니 이것을 기록하라
So let it be done

그리고 행하여라
I'm sent here by the chosen one

나는 선택받아 이곳에 왔느니라
So let it be written

그러니 이것을 기록하라

So let it be done

그리고 행하여라
To kill the first born pharaoh son

파라오의 장남에게 죽음을...
I'm creeping death

나는 서서히 다가오는 죽음이다.....

 

Korean Lyric By. Kyle Park

'이것저것 > 음악' 카테고리의 다른 글

[펌] Incubus - Drive  (0) 2005.08.31
[펌] Mind Revolution - Skyfire  (0) 2005.08.22
[펌] Tommy Emmanuel - Classical Gas  (0) 2005.08.22
[펌] Tommy Emmanuel  (0) 2005.08.22
[펌] Feel so good  (0) 2005.06.09
Posted by tornado
|

보는 사람의 다리를 가만 두게 하지 않는

아주 신나고 즐거운 연주.

악기와 곡과 사람이 삼위일체가 된 것 같은..

저스틴 킹은 그 속도에 놀랐지만 엠마뉴엘은

거기에다가 관중의 미소도 담을 줄 안다.

 


'이것저것 > 음악' 카테고리의 다른 글

[펌] Mind Revolution - Skyfire  (0) 2005.08.22
[펌] Metallica - Creeping death (Moscow Live)  (0) 2005.08.22
[펌] Tommy Emmanuel  (0) 2005.08.22
[펌] Feel so good  (0) 2005.06.09
[펌] Opus - Live Is Life  (0) 2005.05.18
Posted by tornado
|
Tommy Emmanuel
 
 
                                출처블로그 : kimcg3519님의 블로그
Posted by tornado
|

울집은 중랑천이랑 가깝다.

걸어서 10분, 인라인 타면 4분 걸린다.

 

집에 멍~하니 앉아서 TV 보고 있는데..

친구가 전화와서 중랑천 가서 낚시 하잖다.

 

결정적으로!!   현재 바다낚시에만 전념하기에..

민물 낚시대는 주변의 형,동생들한테 다 넘긴 상태다 ㅡㅡ;

 

얇은 선상낚시대로 할까~ 하다가..

에이~ 인라인이나 탈란다~

 

그리고 인라인 탔다...

아~~ 나이먹어서 그런지... 두시간 타니까 죽갔다 ㅠㅠ;

 

땀 삐질삐질 흘리고... 더위먹은 개 마냥 헐덕 거리다가

홍탁 먹으러 갔다..

홍탁!! 정말 오랜만에 먹었다..

 

근데.. 아줌마가 좀 강하게 해줬나부다...

코가 찡한게.. 죽갔네.. 적응 안된다.

결국!!! 홍탁 남겼다 ㅠㅠ

 

아깝다 ㅠㅠ

 

좀만 약하게 해줬어두.. 다 먹었는데 ㅠㅠ

 

담에는 약하게 삭힌거로... 포식한번 해야겠다.

 

 

'이것저것 > 낙서장' 카테고리의 다른 글

책샀음.  (0) 2005.08.24
에휴.. 올해는 웬지...  (0) 2005.08.23
11000 히트 이벤트!!!  (3) 2005.08.20
[phpschool 펌] 죽이는 가습기  (2) 2005.08.18
프린터 구입  (2) 2005.08.17
Posted by tornado
|
[방문히트이벤트] 11000 히트를 잡아라! (이웃한정)
리오님이 당첨되었습니다.

'이것저것 > 낙서장' 카테고리의 다른 글

에휴.. 올해는 웬지...  (0) 2005.08.23
인라인 + 홍탁....  (2) 2005.08.22
[phpschool 펌] 죽이는 가습기  (2) 2005.08.18
프린터 구입  (2) 2005.08.17
흐헉.. 몇년만에 본거냥~~  (2) 2005.08.11
Posted by tornado
|
Posted by tornado
|
Posted by tornado
|

죽이누만...

 

 

'이것저것 > 낙서장' 카테고리의 다른 글

인라인 + 홍탁....  (2) 2005.08.22
11000 히트 이벤트!!!  (3) 2005.08.20
프린터 구입  (2) 2005.08.17
흐헉.. 몇년만에 본거냥~~  (2) 2005.08.11
10000 히트 이벤트!!!  (2) 2005.07.29
Posted by tornado
|

http://ko.gotdotnet.com/quickstart/default.aspx

 

한글로 정리 잘 되어있음...

Posted by tornado
|
:script -->
:script -->
   
LBP-3200 NEW2005
대기시간 0초!
2400dpi상당×600dpi 고화질 출력
빠른 출력과 내구성 강화
공간 효율성이 뛰어난 초경량 프린터
간편한 드럼,토너 일체형 카트리지 사용

 

내가 쓰려는게 아니고.... 누나가 사달라고 해서리...

카드로 걍 ^^;

 

가격은.... 146,000 원

디앤샵에서 7% 할인 쿠폰 적용해서 13만 오천원 정도에 구입.

거기에 무료 배송 ^^;

 

다나와에서 사는것 보다 더 싸게 사고 무료 배송 까지 크크

'이것저것 > 낙서장' 카테고리의 다른 글

11000 히트 이벤트!!!  (3) 2005.08.20
[phpschool 펌] 죽이는 가습기  (2) 2005.08.18
흐헉.. 몇년만에 본거냥~~  (2) 2005.08.11
10000 히트 이벤트!!!  (2) 2005.07.29
문좀 고쳐주세요 ㅡㅡ;  (0) 2005.07.28
Posted by tornado
|

다른 도메인에 접근하려니... 보안 수준을 낮춰야 하넹...

보안수준 --> 낮음 으로 하면 될꺼임 ㅡㅡ;

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>XML 로 블로그 읽어오기 </TITLE>

<script language="javascript">
<!--

 var req;

 function GetBlogItem(arg1){

  if(arg1 < 0){
   return false;
  }

  if (document.all) {
   req = new ActiveXObject("Msxml2.XMLHTTP");
  } else {
   req = new XMLHttpRequest();
  }

  if(req){
   req.onreadystatechange = processBlogItem;

   req.open("GET", arg1, true);
   req.send();
  }
 }

 function processBlogItem(){

  // States are: 0 uninitialized
  //      1 loading
  //      2 loaded
  //      3 interactive
  //      4 complete

  if(req.readyState == 4){
   if(req.status == 200){
    var channelXML = req.responseXML.selectNodes("//rss/channel");
    var itemXML = req.responseXML.selectNodes("//rss/channel/item");    
    var contents = "<table border=1 width=100%>"
    
    // TITLE
    contents += "<tr><td height=100 colspan=3><a href='" + channelXML[0].selectSingleNode("link").text  + "'>"
     + channelXML[0].selectSingleNode("title").text  + "</a>"
     + "<BR><font color=gray>" + channelXML[0].selectSingleNode("description").text  + "</font>"
     + "</td></tr>";

    for(var i = 0; i < itemXML.length; i++){
     contents += "<tr>"
      + "<td><a href='" + itemXML[i].selectSingleNode("link").text  + "'>" + itemXML[i].selectSingleNode("title").text+ "</a></td>"
      + "<td>" + itemXML[i].selectSingleNode("category").text + "</td>"
      + "<td>" + itemXML[i].selectSingleNode("pubDate").text + "</td>"
      + "</tr>"
      + "<tr>"
      + "<td colspan=3><PRE>" +  itemXML[i].selectSingleNode("description").text.replace(/<.+?>/g, '') + "</PRE></td>"
      + "</tr>"
    }

    contents += "</table>";

    var divObj = document.getElementById("blogContent");

    divObj.innerHTML = contents;

   }
  }
 }


//-->
</script>
</HEAD>

<BODY>

<form name="TestForm">

<select name="blogList" onchange="GetBlogItem(this.options[this.selectedIndex].value)">
 <option value="-1">--선택--</option>
 <option value="http://blog.naver.com/post/postXMLList.jsp?blogId=yheesung">Tornado의 블로그</option>
 <option value="http://blog.naver.com/post/postXMLList.jsp?blogId=asdkf20">박종복</option>
 <option value="http://blog.naver.com/post/postXMLList.jsp?blogId=lottoangma">lottoangma ♥ skill</option>
</select>
</form>

<div id="blogContent"></div>

</BODY>
</HTML>

Posted by tornado
|

현재 시각... 2005 년 08 월 11일 목요일 오전 1시 10분..;

내 고향은 서울 성북구 안암동이다..

학교도 거기서 다녔고... 어릴때 추억은 거의 대부분 이곳에 있다..

광주사태때 형님들(시국사범이라고 했던 냥반들 ㅡㅡ) 을 아버지가 마루 밑에 숨겨주셨던거 하고..

전경들 울 집에서 식수 떠가고 했던것들 ㅡㅡ; 

 

오늘 간만에 안암동에 갔다 ..

술한잔 거나하게 마시고..  친구랑 편의점 앞에서.. 이런저런 얘기하고 있는데.. 헐..

낯익은 얼굴이 지나간다...

나도 모르게 일어나서 소리질렀다..

 

나 : " 어~! 야.. 너  씨바.. 윤맹 아냐? "

그넘 : "어? 너 쉬파.. 이름 뭐더라??"

나 : " 야이 도그쉐이.. 이름 까묵었나?"

그넘 : "아.. 맞다.. 혜성이..."

나 : " 이런 개늠쉐리.. 희성이다"

그넘 : "우아~~ 이게 몇년 만이냐~~"

 

이렇게 시작된 얘기가... 한시간.. 두시간.. 세시간이 지나고... 방금전까지 ㅎㅎㅎ

86년에 같은반이였으니까..

19년 만에 만났네...

너무 반가워서.. 소주 겁나 마시고.. 전화번호 교환하고...

담에 보자고 헤어졌는데.. 햐~~~ 좀 아쉽네~~

 

그래도 너무 반가웠다...

개늠시키.. 나이가 몇살인데.. 나처럼 장가두 안갔냐~~~~

 

중학교2학년때 같은 반이였는데..

그리고 서로 잊고 지내다가 19년 후에 봤는데 서로 알아보다뉘~

정말 둘다 대단하다.. ㅋㅋ

근데 눈 ?어진거는 여전하구만~ ㅋㅋㅋ

'이것저것 > 낙서장' 카테고리의 다른 글

[phpschool 펌] 죽이는 가습기  (2) 2005.08.18
프린터 구입  (2) 2005.08.17
10000 히트 이벤트!!!  (2) 2005.07.29
문좀 고쳐주세요 ㅡㅡ;  (0) 2005.07.28
세상 사는 이야기??  (0) 2005.07.28
Posted by tornado
|

[링크]SmartClient

JAVA/JEE 2005. 8. 10. 10:37
Posted by tornado
|
function autoHTML( strSrc,optAtt ) {  
// This function will make http,https,ftp,www and email strings clickable.
strSrc = strSrc.replace( /\s(https:\/\/|http:\/\/|ftp:\/\/|www.)([^\s]*)/gi,
' <a href=http://$2 ' + optAtt + '>$1$2</a>' );
strSrc = strSrc.replace( /\s([^\s]*@[^\s]*)/gi,' <a href=mailto:$1>$1</a>' );
return strSrc;
}
function smartRmHTML( strSrc ) {
// Strip off HTML tags. Better than other removeHtml functions out there.
return server.HTMLEncode( strSrc.replace( /<[^<|>]+?>/gi,'' ) );
}
function listAllLinks( strSrc,blnClickable,optAtt ) {
// Extract every link in string and list them in order.
var arrAllLinks
if ( !blnClickable ) {
arrAllLinks = strSrc.match(/(https:\/\/|http:\/\/|
ftp:\/\/|www.)([^\s]*)/gi );
return arrAllLinks.join( ',' );
}
else {
arrAllLinks = strSrc.match(/(https:\/\/|http:\/\/|ftp:\/\/|www.)([^\s]*)/gi );
return arrAllLinks.join( ',' ).replace( /(https:\/\/|http:\/\/|ftp:\/\/|www.)([^,]*)/gi,
'<a href=http://$2 ' + optAtt + '>$1$2</a>' );
}
}
Posted by tornado
|

http://tortoisesvn.tigris.org/download.html 

요기서 다운로드 받아서 해결함 .

관건은 .svn 을 _svn 으로 바꿔줘야 하는데 ㅡㅡ;

절라게 헤맬뻔하다가.. 찾음

 

Special version for Win2k/XP: (We provide NO support for this!) uses _svn folders instead of .svn to work around the VS.NET bug with web projects. If you don't use web projects then please use the official version. Note: working copies created by this version are incompatible with other Subversion clients!Download

 

Posted by tornado
|
 Enterprise Java Technologies Tech Tip에 오신 여러분을 환영합니다
Enterprise Java Technologies
테크팁
2005년 7월 26일자
 
Java 2 Platform, Enterprise Edition (J2EE)에 기반한 enterprise Java technologies 와 APIs의 사용에 관한 최신 정보를 얻어 가시기 바랍니다.

이번 호에서는,

» JAX-RPC를 사용하여 간단한 웹서비스 구현하기
» JAXB로 RELAX NG 사용하기

를 다루게 됩니다.


이 글에서는 Java 2 Java 2, Enterprise Edition, v 1.4 를 사용합니다.
다운로드

저자 Robert Eckstein

JAX-RPC를 사용하여 간단한 웹서비스 구현하기
 

이미 웹 서비스와 자바 기술 대해 작성된 문서들이 많이 있다. 이 중 심도깊은 내용을 다루는 문서도 있었지만, 사람들은 여전히 자바 기술을 사용하여 웹 서비스를 생성하도록 도와주는 간결하고 직접적인 문서를 원한다. 이번 테크팁은 이를 위한 것이다. 간단한 웹 서비스를 구축하는 과정과 XML기반의 RPC(JAX-RPC)를 위해 Java API를 사용하여 서비스에 접근하는 클라이언트를 구축하는 과정에 대해 단계적으로 다룬다. 이 단계는 J2EE 1.4 tutorial에 있는 Chapter 8: Building Web Services with JAX-RPC를 기반으로 한다. 이들은 웹 서비스와 웹서비스의 클라이언트를 생성하는 기본적인 단계들이다.
  1. 서비스를 위한 위한 SEI(service endpoing interface)와 SEI의 실행 클래스 코드를 작성한다.
  2. SEI와 실행클래스를 컴파일한다.
  3. WSDL과 매핑 파일들을 생성한다.
  4. 서비스를 패키지화하고 배치한다. 특별한 동일 클래스들(클라이언트와의 커뮤니케이션에 사용된)은 서비스가 배치되는 동안에 응용서버에 의해 생성된다.
  5. 클라이언트 클래스 소스를 작성한다.
  6. Stub 파일들을 생성한다.
  7. 클라이언트 클래스들을 컴파일한다.
  8. 클라이언트를 패키지화한다.
SEI와 실행 클래스 코드 작성

JAX-RPC 웹 서비스를 개발하는 데 있어서 시작 포인트는 SEI(service endpoint interface)이다. 이것은 단순히 클라이언트가 그 서비스에 호출할 수 있는 방법을 선언하는 자바 인터페이스이다.

JAX-RPC를 통하여 클라이언트들에게 사용 가능한 웹서비스를 만들어 주기 위해 2개의 자바 클래스를 생성할 필요가 있다. 하나는 SEI를 정의하는 것, 그리고 다른 하나는 SEI 구현하는 것이다. 이 두 클래스들의 소스 코드는 이번 테크팁의 샘플 코드인 ttmay2005-ws.jar를 사용한다. 다음은 웹 서비스를 위한 SEI를 정의하는 클래스이다.
   package helloservice;   import java.rmi.Remote;   import java.rmi.RemoteException;   public interface HelloIF extends Remote {       public String sayHello(String s) throws RemoteException;   } 
SEI는 다음의 규칙을 따라야 한다.
  • java.rmi.Remote 인터페이스를 확장한다.
  • public / final / static과 같은 일정한 선언을 가져서는 안된다.
  • 메소드들은 java.rmi.RemoteException이나 그것의 하위 클래스들 중의 하나를 throw해야한다. (메소드들은 또한 service-specific exception들을 throw할 수 있다.)
  • 메소드 매개변수들과 리턴 타입들은 반드시 JAX-RPC타입들에 의해 지원되어야한다. (JAX-RPC 타입 목록를 위해)
다음은 실행 클래스의 코드이다. 이 클래스는 문자열 매개변수를 수용하며, 그 매개변수를 약간 수정된 문자열을 리턴하기 위해 사용한다.
   package helloservice;   public class HelloImpl implements HelloIF {       public String message = "Hello there, ";       public String sayHello(String s) {           return message + s;       }   } 
SEI 클래스와 실행 클래스 컴파일하기

SEI 클래스와 실행 클래스를 생성한 후에는 그들을 컴파일해야한다. 이를 위한 쉬운 방법은 ant 설정 도구(http://ant.apache.org/)를 사용하는 것이다. 웹 서비스를 위한 구축 파일(build.xml)은 이 팁의 샘플 코드에 있다. 샘플을 위한 구축 파일과 같은 디렉토리에서 ant를 실행하여 구축할 수 있다. 현재의 디렉토리를 그 샘플 코드를 설치한 ws/helloservice 밑으로 변경한다. 그리고 다음의 명령을 입력한다.
   ant 
빌드하는데 가장 먼저 이뤄지는 것은 웹서비스를 위한 디렉토리를 생성하는 것이다. 그런 다음 파일들을 컴파일한다. 컴파일 단계는 다음의 javac 명령어들을 실행하는 것과 동일하다.
   src\helloservice>javac -d ..\..\build -cp ..\   ..\build HelloIF.java      src\helloservice>javac -d ..\..\build -cp ..\..\   build HelloImpl.java
(참고: 각각의 명령은 이 문서상에서는 두 줄로 나타내지만 실제로는 한 라인에 입력해야 한다.)

WSDL과 매핑 파일들의 생성

WSDL 파일은 웹서비스를 표현한다. 클라이언트에게 그 서비스에 대한 요구를 하는 데 있어서 어떤 포맷을 이용해야 하는 지를 말해주는 것이 바로 WSDL 파일이다. Wscompile는 JAX-RPC SEI와 WSDL 파일 사이에 매핑을 제공하는 J2EE 1.4 SDK에 패키지된 툴이다. SEI로부터 WSDL 파일을 생성시키거나 WSDL 파일로부터 SEI를 생성시키기 위해 wscompile툴을 구동할 수 있다. 이 만약 이 팁을 위한 구조를 설정하기 위해 ant 명령어를 사용하게 되면, 그것은 wscompile 도구를 구동하여 웹서비스를 위한 WSDL 파일을 생성한다. 그 구조는 또한 mapping.xml 파일을 생성하는데, 매핑 파일은 웹서비스의 WSDL 정의를 자바 인터페이스에 매핑한다.

만약 ant로 빌드하지 않는다면 디렉토리의 안에 다음의 명령을 구동하여 mapping.xml과 WSDL 파일을 새로 만들 수 있다.
   wscompile -define -mapping build\mapping.xml -d build    -nd build -classpath build config-interface.xml
(참고: 이 문서상에서는 두 줄로 나타내지만 실제로는 한 라인에 입력해야 한다.)

wscompile 명령에 있는 플래그는 각각 다음과 같은 의미이다.
-classpath. build 디렉토리에서 SEI를 읽도록 wscompile 툴을 지시한다. -define. WSDL을 생성하도록 wscompile을 지시한다.-mapping. 매핑 파일을 생성하도록 wscompile를 지시한다.  -d. Build 하위 디렉토리에 클래스 파일을 쓰도록 wscompile를 지시한다. -nd. Build 하위 디렉토리에 WSDL 파일을 쓰도록 wscompile를 지시한다. 
wscompile 툴을 구동할 때, 또한 SEI에 대한 정보를 명시하는 wscompile 구성 파일을 제공해야 한다. 구성 파일은 이 테크팁의 샘플 코드로 제공되는데, 그 구성파일은 config-interface.xml이라 하며 다음의 내용을 포함하고 있다.
   <?xml version="1.0" encoding="UTF-8"?>   <configuration      xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">     <service          name="MyHelloService"          targetNamespace="urn:Foo"          typeNamespace="urn:Foo"          packageName="helloservice">         <interface name="helloservice.HelloIF/>     </service>   </configuration>
이 구성 파일은 wscompile에게 MyHelloService.wsdl라는 이름의 WSDL 파일을 생성하도록 명령한다. 그 파일은 또한 다음의 정보와 명령을 제공된다.
  • 서비스명은 MyHelloService이다.
  • SEI는 helloservice.HelloIF이다.
  • helloservice 패키지에 그 서비스 클래스를 놓는다.
  • WSDL 대상과 타입 네임 스페이스는 urn:Foo이다. 네임 스페이스로 무엇을 이용할 것인지는 사용자가 선택할 수 있다. 네임 스페이스의 역할은 자바 패키지 이름의 사용과 비슷하다.즉, 그렇지 않으면 충돌할 수 있는 이름을 식별하는 것이다. 예를 들어, 어떤 회사는 회사의 모든 자바 코드가 com.wombat.* 패키지 안에 있도록 결정할 수 있다. 마찬가지로, 또한 네임스페이스 http://wombat.com을 사용하기로 결정할 수도 있다.
서비스의 패키지와 배치

그 다음으로 서비스를 패키지화하고 배치시킬 필요가 있다. 이를 위해서는 배치 기술어에 서비스에 대한 세부사항을 명시할 필요가 있다. 웹 서비스는 서블릿이나 비상태유지 세션빈(관련된 서비스를 하는데 상태정보를 유지하지 않은 bean;stateless session bean)으로써 구현될 수 있다. 웹 서비스는 서블릿들이 Web Archive (WAR) 파일에 패키지됨에 따라 구현된다. WAR 파일에 있는 WEB-INF 디렉토리는 웹 어플리케이션(web.xml, sun-web.xml)과 특별한 웹 서비스 배치 기술어 파일(webservices.xml)을 위한 두 개의 표준 배치 기술어 파일을 포함한다. 웹 서비스는 Bean이 EJB-JAR 파일에 비상태유지 세션 빈이 패키지됨에 따라 구현되며, 배치 기술어 파일은 META-INF 디렉토리에 있다.

이번 테크팁을 빌드를 하기 위해 ant 명령을 사용한다면, 사용자를 위해 서비스를 패키지한다. 특히 이 빌드는,
  • WAR 내용을 모으기 위해 임시 디렉토리를 생성한다.
  • 임시 디렉토리에서 두 하위디렉토리(WEB-INF와 build)를 생성한다.
  • WEB-IN디렉토리에서 두 하위 디렉토리(클래스들과 wsdl)를 생성한다.
  • HelloIF.class와 HelloImpl.class를 WEB-INF/classes 디렉토리로 복사한다.
  • MyHelloService.wsdl을 WEB-INF/wsdl 디렉토리로 복사한다.
  • mapping.xml 파일을 그 구축 디렉토리로 복사한다.
  • 임시 디렉토리로부터 WAR 파일을 새로 만든다. WAR파일은 WEB-INF 디렉토리에서 web.xmlsun-web.xml 배치 기술어, webservices.xml 파일을 둔다.
다른 대안으로, J2EE 1.4 Application Server의 배치 툴 유틸리티을 사용하는 웹서비스를 패키지 할 수 있다.

WAR 파일이 새로 만들어진 후에는, 이를 deploytool이나 다른 어플리케이션을 사용하여 배치시킬 수 있다. 배치가 성공적이면, 웹브라우저에 URL http://localhost:8080/ttmay2005/hello?WSDL를 입력하여 배치된 서비스의 WSDL 파일을 보게될 것이다.. (Application Server가 port 8080에 배치되었다고 가정). 그 다음 세션(“데스크탑 클라이언트”)에 있는 wscompile 명령이 성공하기 위해 서버로부터 이 XML파일을 다운로드 하는 것에 의존하기 때문에 이를 실행할 수 있음을 주의하기 바란다.

클라이언트 클래스 생성

그 웹서비스를 배치시킨 후에는, 클라이언트 프로그램으로부터 웹서비스에 접근할 수 있다. HelloClient는 이 테크팁의 샘플 코드로 제공된 데스크탑 클라이언트 프로그램이다. 이는 MyHelloService의 sayHello 메소드를 호출한다. 원격 서비스를 위한 프록시(proxy) 를 사용하는 지역 객체인 stub을 통해 이 호출을 하게 된다. stub이 개발 시간(실행시간과 대조적)에 생성되기 때문에, 그것은 보통 정적stub(static stub)이라고 불린다. 다음은HelloClient (정적 stub을 위한 코드)에 대한 원시 코드이다.

   package staticstub;   import javax.xml.rpc.*;   public class HelloClient {       private static String endpointAddress =           "http://localhost:8080/ttmay2005/hello";       public static void main(String[] args) {           System.out.println("Endpoint address = "             + endpointAddress);           try {              Stub stub = createProxy();              stub._setProperty                (Stub.ENDPOINT_ADDRESS_PROPERTY,                 endpointAddress);               HelloIF hello = (HelloIF)stub;              System.out.println(hello.sayHello("Duke!"));           } catch (Exception ex) {              ex.printStackTrace();           }       }           private static Stub createProxy() {           return                (Stub) (new MyHelloService_Impl().                   getHelloIFPort());       }   }  
Stub 파일들 생성

이전에 언급한 대로, 클라이언트는 서비스에 접근하기 위해 stub로 불리는 로컬 프록시를 사용한다. 따라서 그 서비스에 접근하는 클라이언트를 사용할 수 있기 전에, 그 stub 파일들을 생성해야한다. 이를 실행하는 방법은 wscompile와 같은 툴을 사용하는 것이다. 좀전에 한 것처럼, wscompile툴을 호출하기 위해 ant 명령어를 구동할 수 있다. 현재 디렉토리를 그 샘플 코드를 설치한 곳 밑에 있는 ttMay2005/helloclient 디렉토리로 바꾸기 바란다. 그리고 나서, 다음의 명령을 입력한다.
   ant stubs
Stub 태스크는 다음의 독립 변수를 가진 wscompile 툴을 구동한다.
   wscompile -gen:client -d build -classpath build     config-wsdl.xml 
이 독립 변수는 wscompile이 이전에 생성된 MyHelloService.wsdl 파일을 읽도록 한다. 이 툴은 또한 WSDL 파일과 명령어 줄(command-line) 플래그에 대한 정보에 기반하는 파일들을 생성한다. 특히, “-gen” 클라이언트 플래그는 serializers와 value type과 같은 런타임 파일과 stub들을 생성하도록 wscompile에 지시한다. "-d" 플래그는 툴이 생성된 결과물을 build/staticstub 하위 디렉토리에 쓰도록 명령한다.

wscompile 툴을 구동할 때, 목표 WSDL 파일의 위치를 명시하는 구성파일도 제공해야한다. 구성파일(config-interface.xml)은 이 팁의 샘플 코드로 나와있다. 다음은 config-interface.xml 파일의 내용이다.
   <configuration      xmlns="http//java.sun.com/xml/ns/jax-rpc/ri/config">     <wsdl location="http://localhost:8080/ttmay2005/hello?WSDL"      packageName="staticstub"/>   </configuration>
packageName 속성은 그 생성된 stub에 대해 자바 패키지를 명시한다. WSDL 파일의 위치가 URL으로서 명시된다는 것을 알아두기 바란다. 이는 웹서비스에서 WSDL 파일을 요청하는 wscompile 명령을 야기한다. 이 때문에, 웹서비스는 반드시 올바르게 배치되고 성공을 위한 명령을 위해 구동되고 있어야한다. 웹서비스가 실행되지 않고 있거나 서비스가 배치된 포트가 구성 파일의 포트와 다르다면, 그 명령은 실패할 것이다.

클라이언트 클래스 컴파일하기

다음 단계는 클라이언트 클래스를 컴파일하는 것이다. 이번 테크팁의 예제를 컴파일하려면, 다음 명령을 입력한다.
   ant compile
ant 컴파일 태스크는 src/HelloClient.java를 컴파일하고, 그 구축 하위 디렉토리에 클래스 파일을 작성한다. 다음의 명령을 구동하는 것과 동일하다.
   javac -sourcepath src -d build staticstub.HelloClient.java
클라이언트 패키지화

클라이언트를 생성하는 과거 단계는 이전에 생성된 파일들을 jar 파일 안으로 패키지하는 것이다. 다음 명령을 입력한다.
   ant jar
ant jar 태스크는 ttmay2005.jar이란 이름의 파일을 생성한다. HelloClient.class를 제외하고, ttmay2005jar 안의 모든 파일들은 wscompile에 의해 생성되었음을 알아두기 바란다. 또한, wscompile가 그것이 응용 서버로부터 다운로드 한 MyHelloService.wsdl 화일로부터 읽은 정보에 기반한 HelloIF.class를 생성시켰다는 것도 알아두자.

클라이언트 구동

클라이언트를 실행하기 전에 해당하는 JAR 라이브러리(Java Web Services Developer Pack 1.5 download 참고)클래스 패스를 설정하기 바란다.
   jaxrpc/lib/jaxrpc-api.jar   jaxrpc/lib/jaxrpc-spi.jar   jaxrpc/lib/jaxrpc-impl.jar   jwsdp-shared/lib/activation.jar   jwsdp-shared/lib/mail.jar   jwsdp-shared/lib/jax-qname.jar   saaj/lib/saaj-api.jar   saaj/lib/saaj-impl.jar   jaxp/lib/endorsed/dom.jar   jaxp/lib/endorsed/sax.jar   jaxp/lib/endorsed/xalan.jar   jaxp/lib/endorsed/xercesImpl.jar
다른 방법으로는, 다음과 같이 클라이언트를 실행 시킬 때 클래스패스를 추가 시킬 수도 있다.
   ant run
이 경우 커맨드 라인 창에 다음과 같은 내용이 보인다.
   [java] Endpoint address = http://localhost:8080/ttmay2005/hello   [java] Hello Duke!
추가 정보

JAX-RPC에 대한 추가 정보는, J2EE 1.4 Tutorial의 Chapter 8: Building Web Services with JAX-RPC를 참고하기 바란다.

Back to Top

JAXB로 RELAX NG 사용하기
 

Java WSDP(Java Web Services Developer Pack) 1.5의 JAXB 라이브러리는 기본적으로 RELAX NG을 포함하고 있다. RELAX NG는 XML 문서에 대한 용어를 제공하며, 이는 DTD나 XML 스키마를 대안으로 널리 알려져있다. RELAX NG 스펙은 OASIS(The Organization for the Advancement of Structured Information Standards) 내의 RELAX NG 기술 위원회에 의해 개발되어왔다. 현재 JAXB에서의 RELAX NG 지원은 실험적일 뿐이며 공식적으로 지원되지 않는다. 그러나 만약 RELAX NG를 이용하기 원한다면, 좀 더 실험적으로 JAXB와 함께 사용할 수 있다. 이번 테크팁에서는 JAXB에서 RELAX NG를 사용하는 방법에 대해 설명한다.

RELAX NG를 사용하여 속도 높이기

만약 과거에 DTD를 사용했다면, 이 문서들의 syntax가 종종 상당히 빠르게 암호화(cryptic)한다는 것을 알 것이다. RELAX NG 표준은 XML 문서 유효화를 위해 DTD를 사용하는 것에 대해 XML 기반의 대안을 제공한다. RELAX NG는 정의되지 않은 XML 스키마대신 좀 더 더 기능적인 것을 제공하도록 노력한다. 예를 들어, 다음은 DTD이다.
   <!DOCTYPE addressBook [   <!ELEMENT addressBook (card*)>   <!ELEMENT card (name, email)>   <!ELEMENT name (#PCDATA)>   <!ELEMENT email (#PCDATA)>   ]>
다음은 이와 동등한 RELAX NG이다.
   <element name="addressBook"      xmlns="http://relaxng.org/ns/structure/1.0">     <zeroOrMore>       <element name="card">         <element name="name">           <text/>         </element>         <element name="email">           <text/>         </element>       </element>     </zeroOrMore>   </element>
두 문법 중 RELAX NG syntax가 사용하기 더 쉽다고 말할 수 있다.. 이제 sysbtax를 구축해야하는 다음의 XML 문서를 보자.
   <?xml version="1.0" encoding="UTF-8"?>   <book isbn="0345391802">    <title>  The Hitchhiker's Guide to the Galaxy    </title>    <author>Douglas Adams</author>    <character>     <name>Arthur Dent</name>     <friend-of>Ford Prefect</friend-of>    </character>    <character>     <name>Ford Prefect</name>    </character>   </book>
이 XML 문서에서, 책(book)은 명백히 ISBN 숫자, 제목(title), 저자(author), 하나 이상의 문자(character)를 포함하고 있음을 알 수 있다. 그러나 각 문자는 하나 이상의 개별적인 특성을 나타낼 수도 있다. 즉, 각 문서는 그 문서와 연계된 문법을 갖는다. 이는 다음과 같다.
  A Book must have an ISBN number, a title, an author, and it   must have one or more characters.
다음은 XML 문서를 위한 어휘들을 제공하는 RELAX NG 문법에 대한 예제이다.
   <?xml version="1.0" encoding="UTF-8"?>   <grammar xmlns="http://relaxng.org/ns/structure/1.0">     <start>       <element name="book">         <attribute name="isbn">           <text/>         </attribute>       <element name="title">         <text/>       </element>       <element name="author">         <text/>       </element>       <zeroOrMore>         <element name="character">           <element name="name">             <text/>           </element>           <optional>             <element name="friend-of">               <text/>             </element>           </optional>         </element>       </zeroOrMore>     </start>   </grammar>
이는 다음 사항을 나타내고 있다.
  • 문법은 반드시 book이라는 이름의 요소로 구성된다.
  • <book> 요소는 반드시 이와 연계된 <book isbn="0345391802">같은 ISBN 속성을 갖는다.
  • book 요소에는 반드시 <title><author> 요소가 있어야한다.
  • <title><author> 요소 안과 ISBN 속성 내에는 일반 텍스트가 있어야한다.
  • There can be zero or more <character> elements.
  • 0개 이상의 <character>요소가 있을 수 있다.
  • <character>요소는 <name>요소와, 선택적으로 <friend-of>, <since>, <qualification>요소를 가진다. 이 네 요소는 모두 텍스트로만 구성된다.
만약 XML에 대해 알고 있다면 RELAX NG은 쉬울 것이다. 사실, RELAX NG를 XML에서 재형성된 DTD로 생각해도 된다.

RELAX NG 명세

RELAX NG 문법에 대해 좀 더 자세하게 알아보자.

<start> 요소는 RELAX NG 문법이 시작되는 곳을 명시한다. 이름 속성을 가지는 곳인 <define> 요소가 하나 이상 있을 수 있다. 이 정의된 요소들은 같은 이름을 명시하는 <ref> 요소로 참조될 수 있다. 따라서, 예제는 다음과 같다.
   <grammar>     <start>       <ref name="AddressBook"/>     </start>     <define name="AddressBook">       <element name="addressBook">         <zeroOrMore>           <ref name="Card"/>         </zeroOrMore>       </element>     </define>     <define name="Card">       <element name="card">         <ref name="Name"/>         <ref name="Email"/>       </element>     </define>     <define name="Name">       <element name="name">         <text/>       </element>     </define>     <define name="Email">       <element name="email">         <text/>       </element>     </define>   </grammar>
RELAX NG는 DTDs와 다른 많은 언어들과 비슷한 숫자 패턴 정량화(numerical pattern quantification)를 사용한다. 이는 다음과 같다.

<oneOrMore>. 적어도 하나 이상으로 구성된다.

<zeroOrMore>. 하나 이상으로 구성되거나 생략될 수 있다.

<optional>. 하나의 인스턴스로 구성되거나 생략될 수 있다.

In addition, if you want to specify a sequence of patterns at the same level, there are three different elements that you can use: <choice>, <group>, or <interleave>. 이에 덧붙여, 같은 레벨에서 패턴의 시퀀스를 명시하기 원한다면 사용할 수 있는 세 개의 다른 요소, <choice>, <group>, <interleave>가 있다.

<choice>.는 하나를 가리키며, 내부의 여러 개의 요소 중 하나만이 명시될 수 있다. 예를 들면,
     <choice>       <element name='femaleName'>           <text/>       </element>       <element name='maleName'>           <text/>       </element>   </choice>
<group>.은 내부의 요소들을 그룹화한다. 전체 그룹은 외부 수식어로 작용할 수 있다. 예를 들면,
      <oneOrMore>        <group>            <element name='areaCode'>                <text/>            </element>            <element name='phoneNumber'>                <text/>            </element>        </group>   </oneOrMore>
<interleave>. 그 안에 지정된 다른 시맨틱을 준수하는 한, 차일드(child) 요소를 다른 명령에도 나타날 수 있게 한다.

<list> 요소는 토큰(token)의 시퀀스가 반드시 매치되는 패턴을 포함한다. 예를 들어 공백에 의해 나누어지는 두 개의 부동소수점 숫자를 포함하는 벡터(vector)를 갖고자 한다면, 다음과 같이 리스트를 사용할 수 있다.
   <element name="vector">     <list>       <data type="float"/>       <data type="float"/>     </list>   </element>
merging inline pattern등 다른 흥미로운 RELAX NG 문법 부분은 RELAX NG tutorial에서 좀 더 자세히 알아보기 바란다.

Birthday 예제 다시 해보기

다음 예제는 RELAX NG를 이용한 XML Binding(JAXB)를 위한 Java API를 사용하여 설명하고 있다. 이 예제의 소스 코드는 이번 테크팁의 샘플 코드인 ttmay2005-rng.jar에서 제공하고 있다. 여기에서는 지난 2005년 2월 JAXB 테크팁에서 XML 스키마를 사용한 것을 RELAX NG로 변경하였다.

다음은 예제에서 사용된 XML 파일(birthdate.xml)이다.
<?xml version="1.0"?><birthdate>    <birthdayMonth>January</birthdayMonth>    <birthdayDay>21</birthdayDay>    <birthdayYear>1983</birthdayYear></birthdate>
다음은 XML 파일을 위한 규칙을 명시하는 RELAX NG 문법이다 . 문법은 birthdate.rng 파일에 있다. 이 파일은 우선 원시 RELAX NG 형식으로 나타나고, JAXB 요소는 없다. 따라서 위의 XML 파일이 어떻게 유효화되는지 알 수 있다.
<?xml version="1.0"?><grammar xmlns="http://relaxng.org/ns/structure/1.0"         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">           <start>     <element name="birthdate">        <element name="birthdayMonth">            <data type="string"/>         </element>                    <element name="birthdayDay">            <data type="integer"/>         </element>                   <element name="birthdayYear">            <data type="integer"/>          </element>     </element>  </start> </grammar>
이 버전은 JAXB 바인딩을 추가하여 RELAX NG 문법 내의 각각의 요소가 “xjc” 툴이 적절한 소스 코드를 생성하면 어떻게 자바 오브젝트에 바인딩되는지를 가리킨다.
<?xml version="1.0"?><grammar xmlns="http://relaxng.org/ns/structure/1.0"         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"         xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"         xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"         jaxb:extensionBindingPrefixes="xjc"         jaxb:version="1.0">    <jaxb:schemaBindings>    <jaxb:package name="birthdate"/>  </jaxb:schemaBindings>    <start>     <element name="birthdate">        <jaxb:class name="Birthdate" />                       <element name="birthdayMonth">                <jaxb:property name="Month" />                <data type="string">                    <jaxb:javaType name="java.lang.String"                     parseMethod="new" printMethod="toString" />                  </data>            </element>                        <element name="birthdayDay">                <jaxb:property name="Day" />                <data type="integer">                    <jaxb:javaType name="java.lang.Integer"                     parseMethod="new" printMethod="toString" />                  </data>            </element>                       <element name="birthdayYear">                <jaxb:property name="Year" />                <data type="integer">                    <jaxb:javaType name="java.lang.Integer"                     parseMethod="new" printMethod="toString" />                  </data>            </element>     </element>  </start> </grammar>
이 버전은 먼저<jaxb:schemaBindings> 내의 <jaxb:package> 요소를 이용하여 정의된 모든 클래스가 "birthdate" 패키지에 있도록 명시한다. 덧붙여서,는 "Birthdate" 클래스에 매핑된다. <birthdayMonth> 요소는 RELAX NG string 데이타 타입을 확인하고 "Month."라는 이름으로 java.lang.String의 read/write 속성에 매핑될 것이다.같은 형태로, <birthdayDay><birthdayYear> 요소는 java.lang.Integer 오브젝트를 사용하는 비슷한 구조에 매핑될 것이다.

다음은 데이터를 JAXB 생성 인스턴스에서 XML 파일로 마샬Marchal)하거나, 또는 XML 파일에서 JAXB 생성 인스턴스로 언마샬(unmarshal)하기 위해 JAXB를 사용하는 Java 코드 (RELAXNGExample.java 파일 내)이다.
  import java.io.File;  import javax.xml.bind.JAXBContext;  public class RELAXNGExample {    public static void main(String[] args) throws Exception {        test(args[0]);           }        private static void test( String fileName ) throws       Exception {                        JAXBContext context = JAXBContext.newInstance("birthdate");                Object o = context.createUnmarshaller().            unmarshal(new File(fileName));         context.createValidator().validate(o);        context.createMarshaller().marshal(o,System.out);    }  }
예제를 구동하기 위해서는, 먼저 XJC 컴파일러를 사용하여 RelaxNG를 컴파일해야한다. XJC가 -relaxng 옵션으로 RELAX NG 사용하도록 요청할 수 있다. 다음의 XJC 명령을 구동하자.
   xjc -relaxng birthdate.rng -d gen-src
RelaxNG 파일 내의 옵션은 birthdate 패키지(코멘트 없이 Birthdate 인터페이스 포함)을 중심으로 하는 소스 코드를 생성할 수 있다.
package birthdate;public interface Birthdate {    java.lang.Integer getDay();    void setDay(java.lang.Integer value);    java.lang.Integer getYear();    void setYear(java.lang.Integer value);    java.lang.String getMonth();    void setMonth(java.lang.String value);}
다음으로, RELAXNGExample 클래스를 컴파일한다. gen-src 디렉토리에 클래스들이 방금 생성되었다. 그 후 컴파일된 클래스들을 구동한다. 컴파일과 구동을 쉽게 하기 위새서는 ant build tool을 이용한다. 구축 파일(build.xml)은 이 테크팁을 위한 샘플 코드에 제공되어 있다. 예제의 구축 파일이 있는 같은 디렉토리에 ant를 구동하여 구조를 설정할 수 있다. 사용자의 현재 디렉토리를 사용자가 샘플 코드를 설치한 릴렉싱 디렉토리로 변경한다. 그리고 다음 명령어를 입력한다.
   ant
다음 화면이 보여질 것이다.
   Buildfile: build.xml   compile:        [echo] Compiling the schema...        ...        [echo] Compiling the java source files...        ...      run:        [echo] Running the sample application...        [java] <?xml version="1.0" encoding="UTF-8"         standalone="yes"?>        [java] <birthdate><birthdayMonth>January</birthdayMonth>        <birthdayDay>21</birthdayDay><birthdayYear>1983        </birthdayYear></birthdate>         BUILD SUCCESSFULTotal time: 4 seconds
Additional Resources

For more information about JAXB, see Chapter 2: Using JAXB.

For more information about RELAX NG, see the RELAX NG tutorial.

For more information on the JAXB RI project.

For more information on the JAXB extensions for RELAX NG.

Back to Top
Posted by tornado
|

.NET 관련 프로젝트 하는 중 부서 를 표현할 일이 생겼다.

 

음악 >> 가요>> 발라드

머 이런 구조로 표현해야 하는데..  적응 안되는 ms-sql 이다..

구조는 PK 값이 있고.. Parent 값으로 부모값을 찾아가는 평범한 형태이다.

 

함수로 구현할까.. 하다가.. 삽질 한번 하고 프로시져로 대충 결과만 나오게 함 ㅡㅡ;

오라클에 start with ... connect by 처럼 하고 싶었으나... 구차니즘과...

스킬의 부족함으로 인해 ㅠㅠ 이렇게 밖에 못함..

 

Create proc DeptSortList(@idx  int)
AS

 Declare @parent as int
 set @parent = 1

 if(@idx < 1) Begin

  select top 1 @idx = idx from dept order by idx asc
 END
  
 select * into #temp_dept from dept where idx = @idx order by idx asc

 WHILE (@parent > 0)
 BEGIN
  
  select top 1 @parent =  parent from #temp_dept order by idx asc
  insert into #temp_dept select a.* from dept a join  #temp_dept b on a.idx = b.parent where a.idx = @parent 
 END 
 SELECT * FROM #temp_dept order by idx asc


GO

 

콜 해보면 그냥 보통 테이블 구조로 특정 부서의 상위 코드가 출력된다.

적당히 가공해서

a >> a_a >> a_a_a >> a_a_a_a

처럼 출력하고 대충대충 링크 걸고.. 대충대충 iframe 으로 보내서 대충대충 입력하면 된다 ㅡㅡ;

'SQL' 카테고리의 다른 글

[mssql] 날짜 형식 convert  (0) 2005.08.26
MySQL 간단백업  (0) 2005.08.24
[펌] START WITH and CONNECT BY in Oracle SQL  (0) 2005.08.01
[mssql] rowcount ....  (0) 2005.06.21
[ms-sql] 실행 계획 보기... 아주 쌩초보다..  (0) 2005.06.20
Posted by tornado
|
The start with connect by clause can be used to select data that has a hierarchical relationship (usually some sort of parent->child (boss->employee or thing->parts).
It is also being used when an sql execution plan is explained.

In the following example, the table from which that data is selected consists of just these attributes: parent and child. We make sure (by means of a uniqe constraint) that the child is uniqe within the table. This is just like in the real life where (as of yet) a child cannot have to different mothers. The data that gets filled into the table is such that a the sum over the childs with the same parent is the value of the parent:

set feedback offcreate table test_connect_by (  parent     number,  child      number,  constraint uq_tcb unique (child));

5 = 2+3

insert into test_connect_by values ( 5, 2);insert into test_connect_by values ( 5, 3);

18 = 11+7

insert into test_connect_by values (18,11);insert into test_connect_by values (18, 7);

17 = 9+8

insert into test_connect_by values (17, 9);insert into test_connect_by values (17, 8);

26 = 13+1+12

insert into test_connect_by values (26,13);insert into test_connect_by values (26, 1);insert into test_connect_by values (26,12);

15=10+5

insert into test_connect_by values (15,10);insert into test_connect_by values (15, 5);

38=15+17+6

insert into test_connect_by values (38,15);insert into test_connect_by values (38,17);insert into test_connect_by values (38, 6);

38,26,16 have no parents (the parent is null)

insert into test_connect_by values (null,38);insert into test_connect_by values (null,26);insert into test_connect_by values (null,16);

Now, let's select the data hierarchically:

select lpad(' ',2*(level-1)) || to_char(child) s   from test_connect_by   start with parent is null  connect by prior child = parent;

This select statement results in:

38  15    10    5      2      3  17    9    8  626  13  1  1216

How must the select statement be read? If Oracle encounters an SQL statement with a start with and a connect by clause in it, it can be thought of proceeded like this:

  for rec in (select * from table) loop    if FULLFILLS_START_WITH_CONDITION(rec) then      RECURSE(rec, rec.parent);    end if;  end loop;  procedure RECURSE (rec_parent in RECORD_MATCHING_SELECT_STMT, field_par IN field_type) is    APPEND_RESULT_LIST(rec_parent);         for rec_recurse in (select * from table) loop      if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child,field_par) then        RECURSE(rec_recurse,rec_recurse.parent);      end if;    end loop;  end procedure RECURSE;

Pruning branches

Sometimes, it might be a requirement to only partially retrieve a hierarchical tree and to prune branches. Here, a tree is filled. Each child is the number of its parent plus a new digit on the right side.
create table prune_test (  parent  number,  child   number);insert into prune_test values (null,   1);insert into prune_test values (null,   6);insert into prune_test values (null,   7);insert into prune_test values (   1,  12);insert into prune_test values (   1,  14);insert into prune_test values (   1,  15);insert into prune_test values (   6,  61);insert into prune_test values (   6,  63);insert into prune_test values (   6,  65);insert into prune_test values (   6,  69);insert into prune_test values (   7,  71);insert into prune_test values (   7,  74);insert into prune_test values (  12, 120);insert into prune_test values (  12, 124);insert into prune_test values (  12, 127);insert into prune_test values (  65, 653);insert into prune_test values (  71, 712);insert into prune_test values (  71, 713);insert into prune_test values (  71, 715);insert into prune_test values (  74, 744);insert into prune_test values (  74, 746);insert into prune_test values (  74, 748);insert into prune_test values ( 712,7122);insert into prune_test values ( 712,7125);insert into prune_test values ( 712,7127);insert into prune_test values ( 748,7481);insert into prune_test values ( 748,7483);insert into prune_test values ( 748,7487);

Now, we want to retrieve the tree, but prune everything below the branch 1 and 71. It would be false to put these into a where clause of the sql statement, rather, it belongs to the connect by clause:

select  lpad(' ', 2*level) || childfrom  prune_teststart with  parent is nullconnect by  prior child=parent   and parent not in (1, 71);    

This returns:

  1  6    61    63    65      653    69  7    71    74      744      746      748        7481        7483        7487

See also another example for pruning.

Do two items stand in a ancestor descendant relationship

Sometimes, one want's to know if two items are in an ancestor descendant relationship, that is if XYZ as grandfather, or grand-grandfather, or ... of ABC. The following template of a query can be used to determine that.
set feedback offdrop table parent_child;create table parent_child(parent_ varchar2(20), child_ varchar2(20));insert into parent_child values (null,  'a')insert into parent_child values (  'a',  'af');insert into parent_child values (  'a',  'ab');insert into parent_child values (  'a',  'ax');insert into parent_child values ( 'ab', 'abc');insert into parent_child values ( 'ab', 'abd');insert into parent_child values ( 'ab', 'abe');insert into parent_child values ('abe','abes');insert into parent_child values ('abe','abet');insert into parent_child values ( null,   'b');insert into parent_child values (  'b',  'bg');insert into parent_child values (  'b',  'bh');insert into parent_child values (  'b',  'bi');insert into parent_child values ( 'bi', 'biq');insert into parent_child values ( 'bi', 'biv');insert into parent_child values ( 'bi', 'biw');

The following query 'asks' for a parent and a supposed child (grand child, grand grand child) and answers the question if the are indeed in an ancester successor relationship.

set verify offselect  case when count(*) > 0 then    '&&parent is an ancestor of &&child' else    '&&parent is no ancestor of &&child' end     "And here's the answer"from  parent_childwhere  child_ = '&&child'start with  parent_ = '&&parent'connect by   prior child_ = parent_;undefine childundefine parent

Features of 9i

sys_connect_by_path

With sys_connect_by_path it is possible to show the entire path from the top level down to the 'actual' child:

Using hierarchical result sets

With this technique, it is possible to show all kind of hierarchical data relations. Here is an example that lists privileges, roles and users in their hierarchical relation.

See also flat hiearchy.

connect_by_root

connect_by_root is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.

I have yet to dig into this subject and will write about it when things become clearer.

connect_by_is_leaf

connect_by_isleaf is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.

I have yet to dig into this subject and will write about it when things become clearer.

connect_by_iscycle

connect_by_is_cycle is a new operator that comes with Oracle 10g and enhances the ability to perform hierarchical queries.

I have yet to dig into this subject and will write about it when things become clearer.


Thanks to Peter Bruhn, Jonathan Schmalze and Jeff Jones who each pointed out an error on this page.


I always try to improve my site. If you see something that could be better, or is simply wrong, feel free to send any suggestions, ideas, comments to rene.nyffenegger@adp-gmbh.ch

This page is hosted by init 7. I am extremely satisfied with this super friendly swiss based company. So, if you're after web hosting or serverhousing, I recommend to take a look at init 7. As an aside, they also provide a free (except phone call fee) dial up (from within Switzerland).

'SQL' 카테고리의 다른 글

MySQL 간단백업  (0) 2005.08.24
[ms-sql] 카테고리 만들던 중...(허접 -.-)  (0) 2005.08.01
[mssql] rowcount ....  (0) 2005.06.21
[ms-sql] 실행 계획 보기... 아주 쌩초보다..  (0) 2005.06.20
MySQL 1067 에러...  (3) 2005.05.20
Posted by tornado
|
[방문히트이벤트] 10000 히트를 잡아라!
아이리님이 당첨되었습니다.

'이것저것 > 낙서장' 카테고리의 다른 글

프린터 구입  (2) 2005.08.17
흐헉.. 몇년만에 본거냥~~  (2) 2005.08.11
문좀 고쳐주세요 ㅡㅡ;  (0) 2005.07.28
세상 사는 이야기??  (0) 2005.07.28
컴백...  (2) 2005.07.22
Posted by tornado
|

나는 현재 다세대 주택에 세들어 산다.

2층에는 주인집이 있는데, 입구가 나와 틀리다.

그런데 내가 들어가야 하는 문이 무지무지 뻑뻑하다.

밤에 문 한번 열려면 쿵쿵 소리도 나고 해서 아주 조심해서 열어야 한다.

 

어제.. 그러니까 2005년 7월 27일 낮 12시 20분 경이였다.

낚시좀 하고 오려고 낚시가방 어깨에 메고, 문을 여는데..

문이 안열린다 ㅡㅡ;

계속 흔드는데 안열린다 ㅡㅡ;

그래서 힘으로 열었다.

 

소리가 좀 컸는데 여지없이 주인 할머니 내려와서 한마디 한다.

아니 문을 왜이리 쾅쾅 여닫냐~! 살살 해라..

기분은 나쁘지만 어르신한테 어케 말대답 하기도 뭐하고 해서 죄송하다고 말씀드렸다.

차 시동거는데 안들어가시고 계속 뭐라 하신다 ㅡㅡ;

 

그래서 말대답 했다 ㅡㅡ; 

 

문 고쳐주세요 ;;

 

낚시질 하고 와보니 약간 부드러워졌는데, 흠.. 한 두어시간 지나니 또 똑같애 지네 ㅎㅎㅎ

문좀 좋은거 갈아주고 뭐라 하세요~~~

 

그리고 혼자사는 노총각이 회사 출근할때 한번, 퇴근할때 한번 여는데

그거 꼬투리 잡아서 뭐하시려고 그리 뭐라 하세요~~

 

 할머니 ... 대문 고쳐주시고 뭐라 하세요 ^^

'이것저것 > 낙서장' 카테고리의 다른 글

흐헉.. 몇년만에 본거냥~~  (2) 2005.08.11
10000 히트 이벤트!!!  (2) 2005.07.29
세상 사는 이야기??  (0) 2005.07.28
컴백...  (2) 2005.07.22
포맷;;  (0) 2005.07.15
Posted by tornado
|