파이썬에서 사용할 수 있는 BeautifulSoup을 이용해 xml 데이터를 sqlite3 DB에 넣는 툴을 만들는 간단한 예입니다.

1. BeautifulSoup 다운로드 및 설치
필요한 파일은 BeautifulSoup 사이트에서 다운로드 받으실 수있습니다. 파이썬 버젼이 2.*이면 3.0* 버젼을 3.*이면 3.1* 버젼중 최신버젼을 다운로드 받습니다. 다운로드가 완료되면 압축을 풀고 터미널에서 아래와 같이 setup.py를 실행합니다.

>python ./setup.py install

2. BeautifulSoup 사용예
1) 셈플 xml 파일 (test.xml)
테스트를 위해 간단히 작성해본 XML 입니다.
<?xml version='1.0' encoding='UTF-8'?>
<alcohol>
    <cate1 tt="술">
        <cate2 tt="소주">  
            <item>참이슬</item>
            <item>처음처럼</item>
            <item>잎새주</item>
        </cate2>   
        <cate2 tt='맥주'>  
            <item>카스</item>
            <item>라거</item>
            <item>하이트</item>
        </cate2>   
    </cate1>    
    <cate1 tt="안주">  
        <cate2 tt="고가">
            <item>회</item>
            <item>등심</item>
            <item>양곱창</item>
        </cate2>
        <cate2 tt="저가">
            <item>참치캔</item>
            <item>날계란</item>
            <item>새우깡</item>
        </cate2>
    </cate1>   
</alcohol>

2) 파이썬 소스파일 (con_data.py)
  1. #!/usr/bin/python
  2. #  -*- coding: utf-8 -*-
  3.  
  4. import sys
  5. import sqlite3
  6. from BeautifulSoup import BeautifulStoneSoup
  7.  
  8. argCount = len(sys.argv)
  9. if argCount is not 3:
  10.     print 'Usage:con_data.py [xml file] [db file]'
  11.     sys.exit(0)
  12.  
  13. xml_file = sys.argv[1]
  14. db_file = sys.argv[2]
  15.  
  16. #XML open
  17. src = open(xml_file)
  18. soup = BeautifulStoneSoup(src)
  19.  
  20. #DB & Table create
  21. db = sqlite3.connect(db_file)
  22. cursor = db.cursor()
  23.  
  24. cursor.execute("CREATE TABLE item(cate1, cate2, name)");
  25.  
  26. #Insert data
  27. for cate1 in soup.alcohol('cate1'):
  28.     query1 = 'INSERT INTO item VALUES("' + cate1['tt'] + '", "'
  29.     print 'CATE1: ' + cate1['tt']
  30.    
  31.     for cate2 in cate1('cate2'):
  32.         query2 = query1 + cate2['tt'] + '", "'
  33.         print   '\tcate2: ' + cate2['tt']
  34.      
  35.         for item in cate2('item'):
  36.             query3 = query2 + item.string + '")'
  37.             print '\t\t' + item.string
  38.  
  39.             cursor.execute(query3)
  40.     print "---------------------"
  41.  
  42. #Close
  43. cursor.close()
  44. db.commit()
  45. db.close()

3) 테스트
아래와 같이 실행하면 test.db가 생성되어 있음을 확인하실 수 있습니다.


해당 사이트에서 문서 페이지를 읽어 보시면 보다 세부적인 기능과 상세한 사용법을 확인하실 수  있습니다.  사용한 con_data.py외 test.xml은 압축하여 첨부하였습니다. 테스트 시에는 터미널에서 chmod +x ./con_data.py로 실행권한을 설정하셔야 합니다.


모든 댓글을 환영합니다. (욕설과 광고는 삭제합니다.)
  1. gonagi 2009.12.18 20:39  댓글주소  수정/삭제  댓글쓰기

    ㅋㅋ 샘플디비가... ^^;



RSS를 읽어 오는 간단한 리더기를 만들어 보겠습니다. 맥에서는 NSXMLDocument란 편리한 클래스가 있지만 아이폰 SDK에는 포함되어 있지 않습니다. 그렇기 때문에 NSXMLParser를 사용해서 RSS xml을 읽어오는 간단한 샘플을 만들어 보겠습니다.

인터넷을 통해 데이터를 가져오는 부분은 이전  "NSURLConnection으로 웹페이지 내용 가져오기"란 포스팅을 참고 하시기 바랍니다. 여기서는 파싱하는 부분만 간단히 살펴보겠습니다.


1. NSXMLParser 생성
xml 데이터 파싱은 네트워크로 데이터 수신이 완료된 후 불려지는 connectionDidFinishLoading 메소드에서 아래와 같이 처리합니다.

NSXMLParser *parser = [[NSXMLParser alloc] initWithData:receiveData];

[parser setDelegate:self];
[parser parse];
[parser release];

NSXMLParser 오브젝트를 수신된 데이터가 저장된 NSData 타입의 receiveData를 인자로 초기화를 합니다. setDelegate 메소드로 현재 오브젝트를 NSXMLParser의 딜리케이트로 지정합니다. 지정된 오브젝트는 요소별로 파싱의 시작/종료와 파싱된 스트링을 받을 수 있는 메소드를 구현해야 합니다.

parse 메소드로 파싱이 시작됩니다. 파싱은 자동으로 처리되지 않으며, 각 단계별로 딜리게이트된 메소드를 구현하여 필요와 형식에 맞게 직접 처리해야 합니다.

2. Delegate 메소드 구현
NSXMLParser에는 많은 딜리게이트 메소드가 있지만 가장 중요하고 거의 반드시 구현해야될 메소드는 parser:didStartElement, parser:foundCharacters, parser:didEndElement입니다.

parser:didStartElement로 한 요소의 파싱이 시작됨을 알수 있습니다. parser:foundCharacters로 해당 문자열들이 넘어 옵니다. 토큰 단위로 넘어 오기 때문에 넘어 오는 문자열들을 계속 저장해야 합니다. parser:didEndElement가 실행되면 비로소 한 요소의 파싱이 끝난 것을 알 수 있습니다. 이 메소드에서 해당 요소에 따른 필요한 처리를 합니다.

1) 시작 메소드 구현
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"item"])
        elementType = etItem;
   
    [xmlValue setString:@""];
}

두번째 인자인 elementName으로 해당요소의 이름이 전달됩니다. 세번째와 네번째 인자는 네임스페이스와 관련된 uri와 전체이름이 전달됩니다. 만약 해당 xml이 네임스페이스를 사용한다면 이전에 [parser setShouldProcessNamespaces:YES];로 네임스페이스를 처리하도록 설정해야 합니다. NSXMLParser의 shouldProcessANamespace의 기본값은 NO 입니다.

마지막 인자인 attributeDict에는 해당 요소의 속성들이 전달됩니다. 만약 <item lang="ko"> 와 같이 되어 있다면 attributeDict 딕셔너리에 key가 'lang', value가 'ko'로 저장되어 전달됩니다.

여기서는 다른 인자들은 무시하고 item이란 이름의 요소가 시작될때 부터 데이터들을 저장하도록 요소이름이 item인지만 확인합니다. 그리고 xmlValue에 새로운 데이터를 저장하기 위해 이전에 저장된 값들을 초기화합니다.

2) 데이터 저장 메소드 구현
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (elementType == etItem) {
        [xmlValue appendString:string];
    }
}
토큰별로 넘어오는 문자열을 xmlValue에 저장합니다.

3) 종료 메소드 구현
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if (elementType != etItem)
        return;

    if ([elementName isEqualToString:@"title"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"link"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"description"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"category"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"pubDate"]) {
        [currectItem setValue:[NSString stringWithString:xmlValue] forKey:elementName];
    } else if ([elementName isEqualToString:@"item"]) {
        [xmlParseData addObject:[NSDictionary dictionaryWithDictionary:currectItem]];
    }
}

한 요소가 끝날때 호출됩니다. 여기서는 RSS의 title, link, description, category, pubData 항목들만 currentItem 딕셔너리에 저장합니다. 한 포스팅의 마지막 요소인 </item>일 경우에는 xmlParseData에 현재 딕셔너리를 추가합니다.

3. 테이블뷰 출력
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [xmlParseData count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   
    static NSString *CellIdentifier = @"Cell";
   
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
   
    NSDictionary *dict = [xmlParseData objectAtIndex:indexPath.row];
    [[cell textLabel] setText:[dict objectForKey:@"title"]];
   
    return cell;
}

여기서 테이블뷰는 아무 동작을 하지않으며 xmlParseData에 저장된 해당 title만 출력합니다. 빌드 후 실행하면 아래와 같이 해당 RSS의 제목이 출력되는 것을 확인할 수 있습니다.

간단한 RSS 리더기를 구현해 보았습니다. 전체 소스는 아래의 압축파일을 다운로드 받아 확인하실 수 있습니다. 정확하고 자세한 내용은 아이폰 개발자 센터에서 제공하는 Introduction to Event-Driven XML Programming Guide for Cocoa 문서 또는 SeismicXML 샘플코드를 확인하시기 바랍니다.

'iOS' 카테고리의 다른 글

아이폰 OS 4  (8) 2010.04.09
NSXMLParser로 RSS 읽어오기  (21) 2009.08.05
인터페이스빌더 Table View Cell 사용하기  (0) 2009.06.25
cocos2d 개발환경 설정  (24) 2009.04.13
iPhone SDK 3.0 beta 2  (4) 2009.04.05
UITableView의 메모리 누수 현상  (4) 2009.02.05
모든 댓글을 환영합니다. (욕설과 광고는 삭제합니다.)
  1. Favicon of http://icarusx.tistory.com BlogIcon ICARUSX 2009.08.21 13:29  댓글주소  수정/삭제  댓글쓰기

    오오~~ 드뎌... XML 관련 부분을 올려주셨군요 ㅎㅎ

    한동안 휴가다 뭐다 해서 정신없이 잠수를 타고있었네요 ^^
    슬슬 사이트만드는것도 잘되어가고있고..

    바로 만들어봐야겠습니다.. 우선 시간이 않되니.. 즐겨찾기를 쿨럭;;
    감사해요 ㅎ

    뒤늦은 무더위 조심하세요 ㅎㅎ

    P.s : 똑같은 코멘트를 다른곳에 잘못날렸는데... 비번을 까먹었어요 -_-;; 죄송;

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2009.08.24 15:43 신고  댓글주소  수정/삭제

      휴가 잘 갔다 오셨는지요?

      참고만 하시고 애플의 관련 문서와 샘플을 보시는 것이 좋을 것 같습니다. 잘못 달린 댓글을 제가 처리하겠습니다. :)

  2. Favicon of http://icarusx.tistory.com BlogIcon ICARUSX 2009.08.25 10:38  댓글주소  수정/삭제  댓글쓰기

    ^^;; 네 휴가는 잘다녀왓습지요... 벌써 가을로 접어든 모양이에요 ㅎㅎ;; 쌀쌀해지네요 -_-
    감기조심하시길 ㅎㅎㅎ

  3. grogg 2009.09.15 18:39  댓글주소  수정/삭제  댓글쓰기

    아이폰 관련 xml 검색하다가 찾아오게 되었습니다.
    좋은 정보 감사합니다.

  4. skyzzz 2010.03.10 00:03  댓글주소  수정/삭제  댓글쓰기

    첨부해주신 샘플코드를 다운로드 받아서 실행을 해보니 잘되네요.
    근데 의문점이 있어 질문드립니다 ...

    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (elementType == etItem) {
    [xmlValue appendString:string];
    }
    }

    위 부분에서 elementType 과 etItem 변수?는 어디서 나온것인지요?
    답변 부탁드리겠습니다. (__);

  5. BlogIcon 연애사진 2010.03.28 14:01  댓글주소  수정/삭제  댓글쓰기

    안녕하세요, 공개해주신 글을 보고 열심히 따라하며 배우고 있습니다.

    그런데 한가지 여쭤보려고 합니다만 이 RSS의 경우 셀 제목 부분에 본문에 있는 이미지를 부분적으로나마 불러와서 비쥬얼하게 보여주려고 합니다.

    마치 뉴스 앱들의 기사 표현처럼 하려고 한다면 어떻게 해야 할까요?

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2010.04.09 15:58 신고  댓글주소  수정/삭제

      죄송합니다. 댓글을 이제서야 보았네요. UITableViewCell을 커스터마이징해서 사용해야 합니다. 애플 개발자 사이트에 보시면 관련 샘플들이 있습니다.

  6. enigma 2010.04.21 11:47  댓글주소  수정/삭제  댓글쓰기

    정말 감사합니다. 많은 도움 되었습니다.

    제가 cocoadev님 소스를 받아서 더보기버튼(Disclosure Button)을 만들어 UITextView에 <description>에 있는 내용을 나오게 했는데 문자는 잘나오는데 그림같은 경우는 소스그대로 나오더군요 이건 어떻게 처리해야 하는지 조그만 팁 좀 부탁드리면 안될까요? ㅜㅜ

  7. enigma 2010.04.27 11:05  댓글주소  수정/삭제  댓글쓰기

    제가 좀 게을러서 이제야 해결해서 글올립니다. UITextView 보다는 UIWebView에 파싱된 string을 읽는 메소드가 있더군요 그걸로 하니 훨씬 편하고 좋네요...ㅋㅋ
    cocoadev님 덕분에 해결했습니다. 정말 감사합니다...^^

  8. 2010.04.30 14:55  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  9. 2010.05.10 14:41  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2010.05.13 11:22 신고  댓글주소  수정/삭제

      글 하단에 전체 소스코드를 다운로드 받으실 수 있는 링크가 있습니다. 다운로드 받으셔서 소스를 확인해 보시면 될 것 같습니다.

  10. aszin 2010.12.24 09:04  댓글주소  수정/삭제  댓글쓰기

    안녕하세요~~ 파싱에 관한 자료를 찾다가 와서 강의 잘보고 있습니다.^^
    지금은 파싱을 해서 제목만 불러오는데요..제목을 터치하면 페이지가 바뀌면서 본문내용까지
    파싱을 해 오고 싶은데 어떠한 추가적인 작업을 해주어야 하나요??
    혹시 이에 관련된 강의를 해주실 수 있나요??
    가능하시면 부탁드립니다.
    연말연시 잘 보내시고요~~^^

  11. 당근구리 2011.03.02 10:54  댓글주소  수정/삭제  댓글쓰기

    좋은 포스트 잘 보고 갑니다.
    심플하게 정리 잘 하셨네요.
    퍼갈께요~

  12. slamdh 2011.03.22 17:51  댓글주소  수정/삭제  댓글쓰기

    마침 NSXMLParser로 rss읽어오는걸 찾고있었는데 좋은정보 감사드립니다.

    근데 하나 궁금해서 여쭈어볼까합니다.

    어떤싸이트는 되는데 어떤싸이트는 error code 31 이라는게 뜨는데 찾아보니

    EUC-KR을 지원안한다고해서 수정해보았는데 똑같은 에러가 뜹는데 혹시 알수있을까요?



NSURLConnection을 이용하면 간단하게 해당 웹서버의 html, xml등의 내용을 쉽게 가져올 수 있습니다.

1. 연결
connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.cocoadev.co.kr/rss]] delegate:self];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

대상 URL을 인자로 NSURLConnection을 생성합니다. 위는 이 블로그의 rss를 주소로 생성하는 예입니다. delegate는 self로 현제 오브젝트로 지정합니다. delegate로 지정된 오브젝트는 NSURLConnection의 delegate 메소드를 구현하고 메시지를 받을 수 있습니다.

UIApplication의 networkActivityIndicatorVisible을 YES로 하여 데이터 수신 시 좌측과 같이 상단 상태바에 인디케이터가 회전하는 에니메이션으로 사용자에게 데이터 수신중임을 알려줍니다. 기본값은 NO로 되어 있습니다.

2. delegate 메소드 구현
NSURLConnection 생성시 delegate로 지정된 클래스에서는 해당 이벤트 처리 메소드를 구현해야 합니다. 가장 자주 사용되는 delegate 메소드는 데이터 수신, 연결 종료, 오류발생등에 관련된 것들입니다.

1) 데이터 수신
* connection:didReceiveData:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
   [receiveData appendData:data];
}
데이터가 수신될 때 불려지면 웹서버로 부터 받은 데이터가 NSData 형태로 넘어 옵니다. NSMutableData의 appendData 메소드를 이용하여 수신되는 데이터들을 차례대로 저장합니다.

2) 연결 종료
* connectionDidFinishLoading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
   NSString *str = [[NSString alloc] initWithData:receiveData
encoding: NSUTF8StringEncoding];
   NSLog(@"%@", str);
   [str release];

   [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
데이터가 모두 수신되어 웹서버와의 연결이 종료되었을 때 호출됩니다. 이곳에서 원하는 작업을 하거나 다른 오브젝트가 처리하도록 할 수 있습니다. 위는 NSData로 저장된 데이터를 NSString으로 변환하여 출력하는 예입니다. xml이라면 NSXMLParser를 사용하여 데이터를 처리할 수 있습니다.

3) 오류 발생
* connection:didFailWithError:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
   NSLog(@"Connect error: %@", [error localizedDescription]);   

  [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}
네트워크가 연결되지 않았을 경우등 오류가 발생하였을 때 호출되는 메소드 입니다. 해당 페이지가 없음을 나타내는 404 오류등은 이 메소드가 호출되지 않습니다.

모든 댓글을 환영합니다. (욕설과 광고는 삭제합니다.)
  1. 2009.07.10 17:13  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2009.07.10 19:45 신고  댓글주소  수정/삭제

      str에 NSData로 수신된 데이터를 넣으셨나요? 아니면 NSData를 alloc을 하지 않고 사용하셨으면, 오브젝트가 참조시 이미 메모리에서 릴리즈되었는지도 모르겠습니다.

  2. 2009.07.22 15:13  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2009.07.22 17:50 신고  댓글주소  수정/삭제

      필요한 아무 클래스에다 구현하시면 됩니다. 처음에 테스트 해보실려면 AppDelegate가 구현된 클래스나 ViewController 서브 클래스에서 구현하시면 될 것 같습니다.

  3. 2009.07.22 22:23  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  4. 2010.04.06 19:47  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

    • Favicon of https://www.cocoadev.co.kr BlogIcon cocoadev 2010.04.07 15:31 신고  댓글주소  수정/삭제

      오류메시지 없어 정확히 무슨 오류인지는 모르겠습니다만...

      NSURLConnection *connection;

      으로 선언을 안하신 것 같습니다.

  5. html 2010.07.17 04:35  댓글주소  수정/삭제  댓글쓰기

    html을 nsstring으로 출력 할려면 어떻게 해야하죠?

  6. 2010.12.10 01:29  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  7. artesign 2012.08.16 11:02  댓글주소  수정/삭제  댓글쓰기

    팬입니다.. 정말 제가 필요한 정보들이 다 요약정리가 잘되어있네요 ㅜㅜ 파일입출려과 nsurlconnection 등등 ㅜㅜ



flex2로 만든 Tree로 메뉴를 보여주는 샘플 입니다. xml에서 데이터를 읽어 오기 때문에 메뉴 이름이나 URL이 변경되더라도 다시 컴파일할 필요가 없습니다. 그리고 제목을 클릭해도 오픈/클로즈가 가능하고 링크가 있을 시에는 해당 링크가 오픈됩니다.


lmenu.mxml (flex2 소스 파일)
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    creationComplete="initData()" width="180" height="200" fontSize="11">
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            import flash.net.navigateToURL;

            /* murl 파라미터에서 설정된 url로 부터 xml 데이터를 가져 온다. */
            private function initData():void {
                xmlService.url = Application.application.parameters.murl;
                xmlService.send();
            }
           
            /* xml 가져오기 오류 시 메시지 출력 */
            private function faultHandler(event:FaultEvent):void {
                mx.controls.Alert.show(event.fault.message);
            }
           
            /* Tree 마우스 클릭 이벤트 처리 */
            private function onItemClicked(event:Event):void {
                if(event.currentTarget.selectedItem.@data) {
                   
                    /* 현재 선택된 아이템의 데이터 값을 가져 온다. */
                    var dataString:String = "";
                    dataString = event.currentTarget.selectedItem.@data;
                   
                    /* data(link)가 있을 시에는 url을 연다 */
                    if(dataString.length > 0)
                    {
                        var url:URLRequest = new URLRequest(dataString);
                        navigateToURL(url);
                    }   

                    /* 아이템이 열려 있으면 닫고, 닫혀있으면 연다 */
                    var openFlag = !(menuTree.isItemOpen(event.currentTarget.selectedItem) == true);
                    menuTree.expandItem(event.currentTarget.selectedItem, openFlag);   
                }
            }
        ]]>
    </mx:Script>

    <mx:HTTPService id="xmlService" resultFormat="e4x" fault="faultHandler(event)" useProxy="false" />
    <mx:XMLListCollection id="xc" source="{xmlService.lastResult.item}" />

    <mx:Tree id="menuTree" labelField="@label" showRoot="true"
        x="0" y="0" width="180" height="200"
        dataProvider="{xc}" click="onItemClicked(event);" />
</mx:Application>
현재 창에서 링크가 열리기를 원하시면 navigateToURL(url)을 navigateToURL(url, "_self")로 변경합니다.

test.html (html 샘플 파일)
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Flex Menu Test</title>
<script type="text/javascript">
function goURL(url)
{
    document.location.href = url;
}
</script>
</head>
<body>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
            id="flexMenu" width="500" height="400"
            codebase= "http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="[swf url]?murl=[xml url]" />
<param name="quality" value="high" />
<embed src="[swf url]?murl=[xml url]" quality="high" bgcolor="#efefef"
                width="500" height="400" name="flex" align="middle"
                play="true"
                loop="false"
                quality="high"
                type="application/x-shockwave-flash"
                pluginspage="http://www.adobe.com/go/getflashplayer">
            </embed>
    </object>
</body>
</html>
murl로 xml 파일의 url을 전달합니다.

[swf url] 컴파일된 swf 파일의 url입니다.
[xml url] 메뉴 구조가 정의된 xml의 url입니다. 구조는 아래와 같습니다.

src와 movie에서의 내용을http://www.domain1.com/lmenu.swf?murl=http://www.domain2.com/menu.xml 과 같이 입력하시면 됩니다.

menu.xml (메뉴 구조 샘플 파일)
<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item label="포탈 사이트">
        <item label="네이버" data="http://www.naver.com"/>
        <item label="다음" data="http://www.daum.net"/>
        <item label="야후" data="http://www.yahoo.co.kr"/>
        <item label="엠파스" data="http://www.empas.com"/>
    </item>
    <item label="블로그">
        <item label="내 블로그" data="http://www.cocoadev.co.kr"/>
        <item label="올블로그" data="http://www.allblog.net"/>
        <item label="티스토리" data="http://www.tisotry.com"/>
    </item>
</root>
서브 메뉴를 포함하고 있을 때는 "<item>[.. sub item]</item>"과 같이 포함하지 않으면 "<item />"과 같이 사용하시면 됩니다. 링크가 필요한 경우에는 item의 data 필드를 이용합니다.

crossdomain.xml
<?xml version="1.0"?>
<cross-domain-policy>
    <allow-access-from domain="*"/>
</cross-domain-policy>

swf가 있는 도메인과 xml이 있는 도메인이 다를 경우에는 xml이 있는 곳에 위와 같은 crossdomain.xml 파일이 존재하여야 합니다.
모든 댓글을 환영합니다. (욕설과 광고는 삭제합니다.)