XML 표준과 Parser

윤뿔소·2024년 8월 3일
0

CS 지식 / 다양한 팁

목록 보기
15/20
post-thumbnail

XML 표준

XML(Extensible Markup Language)은 데이터를 저장하고 전송하는 데 사용되는 마크업 언어입니다.

정의

XML은 W3C(World Wide Web Consortium)에서 개발한 마크업 언어로, 데이터의 구조를 정의하고, 데이터를 저장하고 전송하기 위해 사용됩니다. XML은 사람이 읽기 쉬운 형태로 데이터를 표현하며, 태그와 속성을 사용해 데이터를 구조화합니다.

목적

  • 데이터 호환성: 비즈니스 간 트랜잭션 등 서로 다른 시스템 간에 데이터 교환을 용이하게 하기 위해 사용
  • 데이터 저장 및 전송: 데이터를 구조화해 저장하고, 네트워크를 통해 안전하게 전송할 수 있도록
  • 플랫폼 독립성: 특정 플랫폼이나 프로그래밍 언어에 종속되지 않고, 다양한 환경에서 데이터를 활용할 수 있음

W3C (World Wide Web Consortium)

W3C는 월드 와이드 웹의 발전을 촉진하기 위해 설립된 국제 표준화 기구입니다. W3C는 XML을 비롯한 여러 웹 표준을 개발하고 유지 관리합니다.

  • 설립 목적: 웹 기술의 표준화를 통해 웹의 잠재력을 극대화하고, 상호 운용성을 보장하며, 웹을 전 세계적으로 확산시키기 위해 설립
  • 역할: 웹 관련 표준 개발, 가이드라인 제공, 기술 문서 발행 등을 수행

XML의 활용 분야

XML은 호환성을 보장해 서로 다른 시스템 간의 데이터 교환이 용이하고, 트리 구조로 돼 있어 문서 저장 및 구조화에도 용이합니다. 그에 따른

1. 웹 서비스 및 API

SOAP(Simple Object Access Protocol) 기반의 웹 서비스는 XML을 사용해 메시지를 구조화하고 교환하고 전송합니다. 이는 서로 다른 언어와 플랫폼 간의 데이터 교환을 용이하게 합니다.

2. 구성 파일

XML은 소프트웨어의 설정 정보를 저장하는 구성 파일 형식으로 많이 사용됩니다. 예를 들어, Java의 Spring 프레임워크에서는 설정 정보를 XML 파일로 작성해 애플리케이션의 동작을 제어합니다.

3. 데이터베이스

XML 데이터베이스는 XML 형식으로 데이터를 저장하고 관리합니다. 이는 비정형 데이터를 효율적으로 저장하고 검색할 수 있는 방법을 제공합니다.

4. 산업 표준

다양한 산업 분야에서 XML 기반의 표준이 사용됩니다. 예를 들어, 금융 분야에서는 금융 정보 교환을 위한 FIX 프로토콜, 출판 분야에서는 문서 교환을 위한 DITA(Document Information Typing Architecture) 등이 있습니다.

참고

XML 표준 정의, 아마존 XML, XML 티스토리


Parser 개념

먼저 정규표현식 개념을 보고 오시면 좋습니다.

파서(Parser)는 입력된 텍스트를 분석해 구조화된 데이터로 변환하는 프로그램입니다. 파서는 다음과 같은 과정으로 작동합니다:

  1. 렉싱(Lexing): 입력 텍스트를 토큰(Token)으로 분할합니다. 각 토큰은 의미 있는 최소 단위입니다.
  2. 구문 분석(Syntax Analysis): 토큰을 사용해 문법 규칙에 맞는 구조로 변환합니다.
  3. 구조화된 데이터 생성: 분석된 데이터를 트리 구조 등의 형식으로 저장합니다.

XML 파싱 개념

XML(Extensible Markup Language)은 데이터 저장 및 전송을 위한 마크업 언어로, 트리 구조를 가지고 있습니다. XML 데이터 파싱은 XML 문서를 읽어 들여 각 요소를 분석하고, 이를 데이터 구조로 변환하는 과정입니다. 이를 통해 데이터의 구조와 내용을 코드에서 사용할 수 있는 형태로 변환할 수 있습니다.

XML 파서 구현 과정

  1. 입력 데이터 준비:
    • XML 데이터 문자열을 준비합니다.
    • 예: android-layout.xml
  2. Prolog 파싱:
    • XML 문서의 맨 처음에 위치하는 Prolog 부분을 파싱합니다.
    • 예: <?xml version="1.0" encoding="utf-8"?>
  3. 주석 제거:
    • XML 데이터에서 주석을 제거해 유효한 XML 요소만 남깁니다.
  4. 태그 및 속성 파싱:
    • 태그와 속성을 파싱해 트리 구조로 변환합니다.
    • 태그 파싱 예:
      const tagRegex = /<([^>]+)>|([^<]+)/g;
  5. 트리 구조 생성:
    • 파싱된 데이터를 트리 구조로 변환해 저장합니다.
    • 각 요소는 element, attributes, value, children을 포함하는 객체로 표현됩니다.
  6. 데이터 구조 탐색 및 변환:
    • 특정 속성을 가진 요소를 찾거나, 요소 종류별 개수를 카운트하는 등의 작업을 수행합니다.

오토마타와 정규표현식, XML, Parser의 관계

정규표현식, XML 표현 같은 복잡한 데이터 형식을 다루는 데 필요한 이론적 기반을 공부하려고 작성해봤습니다.

오토마타 이론 개념

상태(State)와 전이(Transition)로 구성된 수학적 모델.
주로 문자열의 패턴을 인식하거나 계산을 수행하는 데 사용.

유한 상태 기계(Finite State Machine, FSM)는 정규표현식(Regular Expression)과 밀접한 관련이 있습니다. FSM은 입력 문자열을 읽고, 각 문자를 처리해 상태를 전이시킵니다. 이 과정에서 문자열이 특정 패턴에 맞는지 검증할 수 있습니다. 즉, 정규표현식을 만드는데 기반이 된 것이 오토마타 이론인 셈이죠.

정규표현식과 오토마타

  • 정규표현식: 문자열의 패턴을 표현하는 언어.
  • 오토마타 이론에서 유래.
  • 정규표현식을 기반으로 오토마타(유한 상태 기계) 구성 가능.
  • 입력 문자열을 한 문자씩 처리해 패턴 확인.

XML과 정규표현식

  • XML: 데이터를 구조화하는 마크업 언어.
  • 트리 구조로 표현, 태그와 속성으로 구성.
  • XML 파서: XML 데이터를 읽고 분석해 트리 구조로 변환.
  • 정규표현식: XML 태그 추출 및 속성 파싱에 사용.

XML 파서와 오토마타

  • XML 파서: 입력된 XML 데이터를 트리 구조로 변환.
  • 오토마타 이론 적용.
  • 상태 기계처럼 동작, 태그와 속성을 인식하고 처리.
  • < 문자를 만나면 태그 시작, > 문자를 만나면 태그 끝 인식.

정규표현식, Tokenizer, Lexer, Parser의 예시

  1. Tokenizer: 입력 데이터를 토큰(Token)으로 분할하는 과정입니다. 정규표현식을 사용해 XML 태그와 텍스트를 추출할 수 있습니다.

    const tagRegex = /<([^>]+)>|([^<]+)/g;
    const matches = Array.from(content.matchAll(tagRegex));
  2. Lexer: 토큰을 분석하고 의미 있는 단위로 분류합니다.
    태그의 시작과 끝, 속성 등을 식별합니다.

    function parseTag(tag) {
      const isSelfClosing = tag.endsWith('/');
      const tagParts = tag.replace('/', '').trim().split(/\s+/);
      const tagName = tagParts[0];
      const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)\s*=\s*"([^"]*)"/g;
      const attributes = Array.from(tag.matchAll(attrRegex)).map((match) => ({
        name: match[1],
        value: match[2],
      }));
      return { tagName, attributes, isSelfClosing };
    }
  3. Parser: Lexer가 분류한 토큰을 사용해 구조화된 데이터를 생성합니다. XML 데이터를 트리 구조로 변환하고, 이를 사용해 데이터 구조를 탐색하고 변환할 수 있습니다.

    function convertXml(xmlData) {
      const lines = xmlData.split('\n').map((line) => line.trim());
      const prolog = parseProlog(lines);
      const content = removeComments(lines.slice(1)).join(' ');
    
      const parsedData = { prolog, elements: [] };
      const stack = [];
      const tagRegex = /<([^>]+)>|([^<]+)/g;
      const matches = Array.from(content.matchAll(tagRegex));
    
      matches.forEach((match) => {
        if (match[1]) {
          const tag = match[1].trim();
          if (tag.startsWith('/')) {
            stack.pop();
          } else {
            handleOpeningTag(tag, stack, parsedData);
          }
        } else {
          handleTextContent(match[2], stack);
        }
      });
    
      return parsedData;
    }

Tokenizer, Lexer, Parser

Tokenizer는 입력된 원시 데이터를 토큰(Token)이라는 의미 있는 최소 단위로 분리합니다.

const tagRegex = /<([^>]+)>|([^<]+)/g;
const matches = Array.from(content.matchAll(tagRegex));

Lexer는 Tokenizer로 추출한 각 토근에 뭘 나타내는지 식별하고 분류합니다.(태그 시작, 종료, 속성 등)

function parseTag(tag) {
  const isSelfClosing = tag.endsWith('/');
  const tagParts = tag.replace('/', '').trim().split(/\s+/);
  const tagName = tagParts[0];
  const attrRegex = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)\s*=\s*"([^"]*)"/g;
  const attributes = Array.from(tag.matchAll(attrRegex)).map((match) => ({
    name: match[1],
    value: match[2],
  }));
  return { tagName, attributes, isSelfClosing };
}

Parser는 Lexer가 분류한 토큰을 사용해 구조적으로 나타내주는 기능입니다.

function convertXml(xmlData) {
  const lines = xmlData.split('\n').map((line) => line.trim());
  const prolog = parseProlog(lines);
  const content = removeComments(lines.slice(1)).join(' ');

  const parsedData = { prolog, elements: [] };
  const stack = [];
  const tagRegex = /<([^>]+)>|([^<]+)/g;
  const matches = Array.from(content.matchAll(tagRegex));

  matches.forEach((match) => {
    if (match[1]) {
      const tag = match[1].trim();
      if (tag.startsWith('/')) {
        stack.pop();
      } else {
        handleOpeningTag(tag, stack, parsedData);
      }
    } else {
      handleTextContent(match[2], stack);
    }
  });

  return parsedData;
}

handleOpeningTaghandleTextContent 를 호출해 parsedData 의 트리 구조를 만들고 있습니다.

profile
코뿔소처럼 저돌적으로

0개의 댓글