프로그래밍 정리/Ubuntu - C

[Ubuntu - 우분투 - C] libxml2 - Well-formed, Vaild, DTD, xml2-config

주누다 2015. 5. 21. 20:14
반응형

XML

- XML 은 'eXtensible Markup Language' 의 줄임말

- 확장 가능한 마크업 언어 정도의 의미

- HTML이 사람이 읽는 문서를 작성하는데 역점을 두는 반면,

  XML은 주로 데이터 자체를 작성하므로 프로그램에서 이용하기 쉬움

- XML 은 구조화된 데이터를 중첩 구조로 작성

- HTML처럼 시작 태그와 종료 태그의 쌍으로 구조를 지정




Well-formed 문서와 Valid 문서

- XML에는 두 종류의 문서 형식이 있음

- Well-formed(정형식 제약) 문서

- Valid(타당성 제약) 문서


 Well-formed 문서

- 문서에서 이용되는 태그의 관계에 문제가 없으면 적절한 XML문서로 인정

- 태그의 관계가 부적절한 예로 대표적인 것은 중첩 구조가 깨진 경우

ex)

<TAG_A>

  <TAG_B>

    첫 번째 단락

  </TAB_B>

</TAG_A>

<TAG_C>

  <TAG_D>

    두 번째 단락

  </TAG_C>

</TAG_D>


Valid 문서

- 스키마(schema)라고 불리는 문서 구조의 정의가 이용

- 스키마는 그 XML에 주어지는 문법책으로 볼 수 있으며, 문서 구조와 문서 형태를 정의할 수 있음

- 구체적으로 DTD(Document Type Definition)라는 문서로 스키마가 작성

- Valid 문서에서는 데이터의 형도 지정할 수 있으므로 적절한 데이터인지를 좀 더 검사하기 쉬움

- 반면, DTD가 변경될 때마다 데이터도 수정해야 하는 등 융통성이 없다는 단점도 있음

- Valid 문서는 구조체의 정의를 그대로 반영한 문서라고 할 수 있음




libxml2

- XML 데이터를 C 언어에서 다루기 위해 개발된 라이브러리 => libxml2

- 원래는 GNOME 프로젝트용 툴킷으로 개발

- XML의 읽기 쓰기는 범용적으로 사용할 수 있음

- 데이터의 읽고 쓰기는 플랫폼에 의존하지 않아 다양한 플랫폼으로 이식돼 이용 가치가 높은 라이브러리


XML 도큐먼트 데이터 작성과 해제

- 우분투에서 'libxml2'를 이용할려면 'libxml2-dev' 패키지를 설치해야함

- sudo apt-get install libxml2-dev

- 'libxml2-dev' 를 설치하면 'libxml2' 라이브러리와 별개로 개발용 헤더 파일이 '/usr/include/libxml2' 디렉터리 아래에 설치


- xmlParseFile()

  => XML 문서 파일을 해석

  => 결과를 xmlDoc 형 데이터의 포인터로 저장

  => ex) xmlDoc* doc = xmlParseFile(argv[1]);


- xmlDocGetRootElement()

  => XML 문서의 루트 노드를 획득

  => 이 노드를 구하면 나머진 트리를 더듬어 가서 필요한 데이터에 접근할 수 있음

  => ex) xmlNode* root = xmlDocGetRootElement(doc);


- xmlFreeDoc()

  => 사용한 리소스를 해제


- xmlCleanupParser()

  => xml 파서 메모리 정리


- xmlNewDoc()

  => XML 문서를 생성

  => ex) xmlDoc* doc = xmlNewDoc("1.0");


- xmlNewNode()

  => 노드 생성

  => ex) xmlNode* node = xmlNewNode(NULL, "greeting");

  => xmlNewNode() 의 첫 번째 인수로 이름 공간에 관한 데이터를 줄 수 있음


- xmlNodeSetContent()

  => 생성한 노드의 컨텍스트를 줌

  => ex) xmlNodeSetContent(node, "Hello, world!");


- xmlDocSetRootElement()

  => 도큐먼트의 루트 노드로 지정

  => ex) xmlDocSetRootElement(doc, node);


- xmlDocDumpFormatMemory()

  => 버퍼에 덤프

  => 버퍼는 라이브러리 쪽에서 준비하므로 크기에 신경 쓸 필요 없이 그대로 출력하면 됨

  => ex) xmlDocDumpFormatMemory(doc, &xmlbuff, &bufsize, 1);


- xmlFree()

- xmlFreeDoc()

  => 리소스 해제

 




예제

list0732.c


#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

void print_node(xmlNode* start, int depth){
    xmlNode* node = NULL;

    for(node = start; node; node = node->next){
        if(node->type == XML_ELEMENT_NODE){
            int i;
            for(i = 0; i<depth; i++)
                printf(" ");

            printf("%s\n", node->name);
        }
        print_node(node->children, depth+1);
    }
}


int main(int argc, char **argv){
    xmlDoc* doc = xmlParseFile(argv[1]);
    xmlNode* root = xmlDocGetRootElement(doc);

    print_node(root, 0);   
   
    xmlFreeDoc(doc);
    xmlCleanupParser();

    return 0;
}


list0732B.c


#include <libxml/parser.h>

int main(int argc, char** argv){
    xmlNode* node;
    xmlDoc* doc;
    xmlChar* xmlbuff;
    int bufsize;

    doc = xmlNewDoc("1.0");
    node = xmlNewNode(NULL, "greeting");
    xmlNodeSetContent(node, "Hello World!");
    xmlDocSetRootElement(doc, node);

    xmlDocDumpFormatMemory(doc, &xmlbuff, &bufsize, 1);
    printf("%s", (char*)xmlbuff);

    xmlFree(xmlbuff);
    xmlFreeDoc(doc);

    return 0;
}





반응형