XML(Extensible Markup Language)은 데이터를 저장하고 전송하는 데 사용되는 마크업 언어입니다.
XML은 W3C(World Wide Web Consortium)에서 개발한 마크업 언어로, 데이터의 구조를 정의하고, 데이터를 저장하고 전송하기 위해 사용됩니다. XML은 사람이 읽기 쉬운 형태로 데이터를 표현하며, 태그와 속성을 사용해 데이터를 구조화합니다.
W3C는 월드 와이드 웹의 발전을 촉진하기 위해 설립된 국제 표준화 기구입니다. W3C는 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) 등이 있습니다.
파서(Parser)는 입력된 텍스트를 분석해 구조화된 데이터로 변환하는 프로그램입니다. 파서는 다음과 같은 과정으로 작동합니다:
XML(Extensible Markup Language)은 데이터 저장 및 전송을 위한 마크업 언어로, 트리 구조를 가지고 있습니다. XML 데이터 파싱은 XML 문서를 읽어 들여 각 요소를 분석하고, 이를 데이터 구조로 변환하는 과정입니다. 이를 통해 데이터의 구조와 내용을 코드에서 사용할 수 있는 형태로 변환할 수 있습니다.
android-layout.xml
<?xml version="1.0" encoding="utf-8"?>
const tagRegex = /<([^>]+)>|([^<]+)/g;
element
, attributes
, value
, children
을 포함하는 객체로 표현됩니다.정규표현식, XML 표현 같은 복잡한 데이터 형식을 다루는 데 필요한 이론적 기반을 공부하려고 작성해봤습니다.
상태(State)와 전이(Transition)로 구성된 수학적 모델.
주로 문자열의 패턴을 인식하거나 계산을 수행하는 데 사용.
유한 상태 기계(Finite State Machine, FSM)는 정규표현식(Regular Expression)과 밀접한 관련이 있습니다. FSM은 입력 문자열을 읽고, 각 문자를 처리해 상태를 전이시킵니다. 이 과정에서 문자열이 특정 패턴에 맞는지 검증할 수 있습니다. 즉, 정규표현식을 만드는데 기반이 된 것이 오토마타 이론인 셈이죠.
<
문자를 만나면 태그 시작, >
문자를 만나면 태그 끝 인식.Tokenizer: 입력 데이터를 토큰(Token)으로 분할하는 과정입니다. 정규표현식을 사용해 XML 태그와 텍스트를 추출할 수 있습니다.
const tagRegex = /<([^>]+)>|([^<]+)/g;
const matches = Array.from(content.matchAll(tagRegex));
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 };
}
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는 입력된 원시 데이터를 토큰(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;
}
handleOpeningTag
와 handleTextContent
를 호출해 parsedData
의 트리 구조를 만들고 있습니다.