반응형

우선 컴터 초짜인 내가 대충 이해하기로는 Libxml2는 기존의 XML 파서들보다 다양한 인터페이스를 가지고 다양한 언어그룹에서 사용할 수 있는 기능을 포함하고 있는 최신형 XML Parser 인듯 하다. 사용법 또한 간단하여 이번 기회에 공부할 겸 사용해보게 되었다.
설치부터 사용까지 포스팅을 해보아요

-----------------------------------------------------------------------------------------------
설치 환경 - Linux Ubuntu 10.10

libxml2 설치 (명령문 실행 순서대로)

# wget ftp://xmlsoft.org/libxml2/libxml2-2.7.7.tar.gz
# tar xvzf libxml2-2.7.3.tar.gz
# cd libxml2-2.7.3
# ./configure --prefix=/usr/local/xml
# make
# make install
---------------------------------------------------

1. 터미널에서 wget을 통해서 다운을 받아도 되고 직접 FireFox등의 익스플로어를 사용하여 ftp://xmlsoft.org/libxml2/ 에 들어가면
최신버전을 확인하여 다운 받을 수 있다. 참고하자. (해당폴더에 압축파일을 다운 받을 수 있다)



2. 다운 받은 압축파일의 압축을 풀자.
tar 명령어에서 xvzf는 옵션인데 각 옵션의 의미는 아래와 같다.
-------------------------------------------------------- 압축풀때
-x, --extract, --get : 저장된 것에서 풀어낸다.
-v, --verbose : 처리중인 파일을 자세하게 보여준다. (압축푸는 과정 보여줌)
-f, --file [HOSTNAME:]F : 저장 파일 혹은 장치 파일 F에 저장한다.
-z,--gzip, --unzip : gzip으로 압축하거나 푼다.
-j, bzip2 : bzip2 필터를 사용하여 .bz2 파일을 푼다.
-p : 퍼미션을 유지시켜준다.

------------------------------------------------------- 압축할때
-c, --create : 새 저장파일을 만든다.

압축풀기의 예)
1. tar -zvxf (압축대상파일).tar.gz -C (목적폴더위치),
(삭제 명령어 rm -f -R (목적폴더위치)
[출처] 리눅스 tar 명령어 관련 | alan100님 글

3. 어쨋든 압축을 푼 뒤 해당 폴더에 들어간다.
4. ./configure --prefix=/usr/local/xml (여기서 configure는 환경설정, --prefix는 설치시킬 위치를 의미한다)
5. 컴파일 한뒤에 설치까지 끝마친다.

6. 끝 이제 Libxml의 설치를 마쳤다.



libxml2 설치 참고 usr - http://www.ubuntu.or.kr/viewtopic.php?p=73454
libxml2 코드(튜토리얼) 참고 usr - http://kylesoft.springnote.com/pages/5620523
libxml2 라이브러리 참고 usr - http://myweb.bcpark.net/~hosuck/gnu3/?doc=bbs/gnuboard.php&bo_table=PG_JAVASCRIPT&page=1&wr_id=29

gcc -o (dest) (source) -L/usr/local/xml/lib(prefix 한 링크주소) -lxml2(libxml2.so 혹은 a가 있는 주소)

어렵다 -ㅂ-
반응형
반응형

libxml2 란?

개요

제임스 클라크 (James Clark)가 만든 expat 파서를 펄에서 사용할 수 있도록 래리 월 (Larry Wall) 과 클라크 쿠퍼 (Clark Cooper)가 만든 펄 인터페이스 XML::Parse 을 기초로 하여 펄에서 사용되는 대부분의 XML 모듈이 만들어졌다. expat과 XML::Parser 콤비만이 펄 세계에서 유일하게 전 기능을 갖춘 XML 파서는 아니다. 이 기사에서는 대니얼 벨리아드(Daniel Velliard)의 libxml2를 펄에서 사용할 수 있게 해주는 펄 인터페이스 XML::LibXML을 살펴보겠다. 참고로 XML::LibXML는 매트 서전트(Matt Sergeant) 와 크리스챤 글란(Christian Glahn)이 만든 것이다.

또다른 XML 파서가 필요한 이유는 도대체 무엇일까?

물론 expat과 XML::Parser가 훌륭하긴 하지만 그렇다고 해서 아주 단점이 없는 것은 아니다. expat은 XML 파서 중 최초의 그룹에 속했고, 그 결과 작성된 그 시점에서 사용자들의 기대를 반영하는 인터페이스를 가지게 되었다. expat과 XML::Parser가 작성된 시기에는 DOM (Document Object Model), SAX, 또는 XPath 등이 존재하지 않았거나 열띤 논의중이어서 '표준'으로 간주되지 않았기 때문에 이들 언어에 대한 인터페이스를 구현하지 않았다. 그 결과 불행히도 대부분의 펄 XML 모듈들은 XML::Parser의 비표준 내지 표준이라고는 하기 힘든 인터페이스에 기반하여 만들어졌기 때문에 입력이 텍스트로 된 XML 문서로 (파일, 파일핸들, 스트링, 소켓 스트림) 처리하기 전에 파싱이 되어야 한다는 가정을 깔고 있다. 이것들은 단순한 경우에는 대개 잘 작동한다. 그러나 최근의 XML 애플리케이션들은 주어진 문서를 가지고 한가지 이상의 작업을 해야 하므로 처리하는 각 단계마다 문서가 스트링으로 직렬화되고 다음 모듈에 의해 다시 파싱되어야 한다는 단점이 있다.

반면 libxml2는 DOM, XPath, 그리고 SAX 인터페이스가 널리 퍼진 후에 작성되어 이 세 가지 표준을 모두 구현하고 있다. 따라서 lixml로 여러분은 파일, 스트링 등에 저장되었거나 일련의 SAX 이벤트들로부터 만들어진 문서를 파싱하여 메모리에 트리를 만들 수 있다. 이 트리들은 W3C DOM과 XPath 인터페이스를 사용하여 조작할 수도 있고 외부 이벤트 핸들러에 넘겨줄 SAX 이벤트를 만드는데 사용될 수도 있다. 이와 같은 유연성은 요즘의 XML 처리에 대한 기대를 반영하는 것으로 XML::Parser가 차지하고 있는 왕좌의 강력한 도전자로 XML::LibXML을 부상시켜 주었다.

XML::LibXML 사용하기

이 달의 컬럼은 작년 초 필자가 쓴 'Perl/XML Quickstart Guide'란 기사의 속편같이 보일지도 모르겠다. 필자가 그 기사를 쓸 당시에는 XML::LibXML이 아직 성숙하지 않은 상태였기 때문에 Quickstart에서 사용했던 것과 동일한 테스트들을 사용해 XML::LibXML을 시험해 보려고 한다. 테스트 케이스에 대한 자세한 내용은 Quickstart에 대한 첫번째 설치와 관련된 기사를 보면 된다. 요약하자면, 두 테스트는 주어진 XML 모듈에서 제공하는 기능들을 이용해 XML 문서에서 자료를 뽑아내 출력하는 방법과 펄 해시에 저장된 자료로부터 XML 문서를 프로그램적으로 만들고 출력하는지 방법을 보여준다.

읽기

XML 문서에 저장되어 있는 자료에 접근하기 위해 XML::LibXML은 표준 W3C DOM 인터페이스를 제공한다. 문서들은 노드를 가지는 트리로 취급되며 노드가 가지고 있는 자료는 노드 객체에 메소드를 호출하여 접근하게 된다.


use strict;
use XML::LibXML;

my $file = 'files/camelids.xml';
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;
my @species = $root->getElementsByTagName('species');

foreach my $camelid (@species) {
    my $latin_name = $camelid->getAttribute('name');
    my @name_node  = $camelid->getElementsByTagName('common-name');
    my $common_name = $name_node[0]->getFirstChild->getData;
    my @c_node  = $camelid->getElementsByTagName('conservation');
    my $status =  $c_node[0]->getAttribute('status');
    print "$common_name ($latin_name) $status \n";
}
XML::LibXML 의 가장 흥미로운 기능 중 하나는 DOM 인터페이스는 물론이고 추가로 XPath 언어를 이용해 노드를 선택할 수 있다는 점이다. 아래의 코드에서는 XPath를 사용하여 원하는 노드를 선택함으로써 앞의 예제와 동일한 결과를 얻을 수 있음을 보여준다.

use strict;
use XML::LibXML;

my $file = 'files/camelids.xml';
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($file);
my $root = $tree->getDocumentElement;

foreach my $camelid ($root->findnodes('species')) {
    my $latin_name = $camelid->findvalue('@name');
    my $common_name = $camelid->findvalue('common-name');
    my $status =  $camelid->findvalue('conservation/@status');
    print "$common_name ($latin_name) $status \n";
}
위의 코드에서 흥미로운 점은 동일한 노드들의 트리에 DOM 과 XPath 인터페이스의 메소드 중에서 애플리케이션의 필요에 가장 잘 맞는 메소드를 섞어 쓸 수 있다는 것이다.

쓰기

XML::LibXML을 이용해 XML 문서를 만들려면 제공되는 DOM 인터페이스를 사용하기만 하면 된다.

use strict;
use XML::LibXML;

my $doc = XML::LibXML::Document->new();
my $root = $doc->createElement('html');
$doc->setDocumentElement($root);
my $body = $doc->createElement('body');
$root->appendChild($body);

foreach my $item (keys (%camelid_links)) {
   my $link = $doc->createElement('a');
   $link->setAttribute('href', $camelid_links{$item}->{url});
   my $text = XML::LibXML::Text->new($camelid_links{$item}->{description});
   $link->appendChild($text);
   $body->appendChild($link);
}
print $doc->toString;
XML::LibXML과 XML::DOM을 구분하는 중요한 차이점은 libxml2의 객체 모델이 W3C DOM 레벨 2 인터페이스에 맞기 때문에 이것이 XML 네임스페이스를 가지고 있는 문서를 더 잘 다룰 수 있다는 점이다. 따라서 XML::DOM은 아래같이 제한적이다.

@nodeset = getElementsByTagName($element_name);
그리고

$node = $doc->createElement($element_name);
XML::LibXML 은 아래와 같이 할 수도 있다.

@nodeset = getElementsByTagNameNS($namespace_uri, $element_name);
그리고

$node = $doc->createElementNS($namespace_uri, $element_name);
SAX가 제공하는 즐거움

이상으로 우리는 XML::LibXML이 제공하는 DOM과 XPath의 장점을 살펴보았다. 그러나 여기서 이야기가 끝나는 것은 아니다. libxml2 라이브러리는 SAX 인터페이스도 제공하여 SAX 이벤트에서부터 DOM 트리를 만들거나 DOM 트리에서 SAX 이벤트를 만들 수도 있다.

아래의 코드는 XML::SAX::Base에 기반을 둔 SAX 드라이버에서 프로그램을 통해 DOM 트리를 만들어낸다. 이 예제에서 초기 SAX 이벤트들은 CamelDriver 클래스에 구현된 커스텀 드라이버로부터 발생되며 CamelDriver 클래스는 XML::LibXML::SAX::Builder 클래스를 호출하여 DOM 트리를 만든다.


use XML::LibXML;
use XML::LibXML::SAX::Builder;

my $builder = XML::LibXML::SAX::Builder->new();
my $driver = CamelDriver->new(Handler => $builder);
my $doc = $driver->parse(%camelid_links);

# doc is an XML::LibXML::Document object
print $doc->toString;

package CamelDriver;
use base qw(XML::SAX::Base);

sub parse {
  my $self = shift;
  my %links = @_;
  $self->SUPER::start_document;
  $self->SUPER::start_element({Name => 'html'});
  $self->SUPER::start_element({Name => 'body'});

  foreach my $item (keys (%camelid_links)) {
    $self->SUPER::start_element({Name => 'a',
                                   Attributes => {
                                     'href' => $links{$item}->{url}
                                               }
                                });
    $self->SUPER::characters({Data => $links{$item}->{description}});
    $self->SUPER::end_element({Name => 'a'});
  }

  $self->SUPER::end_element({Name => 'body'});
  $self->SUPER::end_element({Name => 'html'});
  $self->SUPER::end_document;

}
1;
XML::LibXML::SAX::Generator를 이용해 기존의 DOM 트리에서 SAX 이벤트를 발생시킬 수도 있다. 아래의 코드에서 camelids.xml 파일을 파싱하여 만들어진 DOM 트리가 XML::LibXML::SAX::Generator의 generate() 메소드에 넘겨지면 XML::Handler::XMLWriter 에 있는 이벤트 핸들러가 호출되어 문서를 STDOUT으로 출력하게 된다.

use strict;
use XML::LibXML;
use XML::LibXML::SAX::Generator;
use XML::Handler::XMLWriter;

my $file = 'files/camelids.xml';
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($file);
my $handler = XML::Handler::XMLWriter->new();
my $driver = XML::LibXML::SAX::Generator->new(Handler => $handler);

# generate SAX events that are captured
# by a SAX Handler or Filter.
$driver->generate($doc);

SAX 이벤트를 받아들이고 내보낼 수 있는 기능은 최근 이 컬럼에서 논의되었던 비XML 자료에서 SAX 이벤트를 발생시키고 SAX 필터 체인을 작성하는 것과 연관지어 생각해보면 아주 유용하다고 볼 수 있다. 예를 들면 펄로 쓰여진 SAX 드라이버를 이용해 데이터베이스 질의에서 가져온 자료에 기반을 두고 이벤트를 발생시켜 DOM 객체를 만들 수 있다. 이 DOM 객체는 C-space에서 디스플레이를 위해 XSLT와 굉장히 빠른 libxslt 라이브러리 (이것은 libxml2 DOM 객체를 기대한다)를 사용해 변환되고, 변환된 DOM 트리에서 커스텀 SAX 필터를 이용한 추가 처리를 위해 SAX 이벤트를 발생시켜 최종 마무리를 한다. 즉 이 모든 것을 하면서 스트링을 다시 파싱하기 위해 문서를 직렬화할 필요가 한 번도 없다는 이야기다. 정말 놀랍지 않은가!

결론

이상 우리가 살펴본 것처럼 XML::LibXML은 XML 처리에 대해 빠르면서도 최신식의 접근방식을 제공한다. 이것은 제 1세대라 할 수 있는 XML::Parser와 비교해 볼 때 보다 여러 가지 방면에서 뛰어나다고 볼 수 있다. 그러나 필자의 말을 오해하지 말길 바란다. XML::Parser와 그에 의존하는 모듈은 여전히 유용하고, 잘 지원되고 있기 때문에 짧은 시간 안에 사라질 위험이 있을 것 같지는 않다. 하지만 그것이 유일한 방법은 아니며 XML::LibXML이 제공하는 유연성을 생각한다면 다음 번 Perl/XML 프로젝트를 시작하기 전에 다시 한 번 XML::LibXML을 자세히 들여다 보라고 강력히 권하고 싶다.

 

저자: 킵 햄튼(Kip Hampton), 역 정직한
출처 : 네이버 리눅스유저 그룹 까페
원본 주소 - http://cafe.naver.com/linuxcare.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=2145



반응형

+ Recent posts