코딩 스쿨 PHP

언어선택 : HTMLCSSJAVAJAVASCRIPTMYSQLSQL PHP

PHP XML Expat

PHP XML Expat : 이벤트 기반 XML 파싱


Expat 파서는 이벤트 기반 XML 파서로, PHP에서 XML 데이터를 처리하는 데 사용됩니다. Expat은 순차적으로 XML 데이터를 읽고, XML 요소의 시작과 끝, 그리고 텍스트 데이터를 처리하는 이벤트를 발생시킵니다. 이벤트 기반 파서는 메모리 효율적이며, 특히 대용량 XML 파일을 처리할 때 유리합니다.

이 가이드에서는 PHP XML Expat 파서를 사용하여 XML 데이터를 파싱하고, 이를 처리하는 방법을 설명합니다.


1. Expat을 사용한 XML 파싱 개념

Expat 파서는 XML 데이터를 순차적으로 읽으며 이벤트를 발생시킵니다. 각 요소(태그)의 시작과 종료, 그리고 텍스트 데이터를 처리하기 위한 콜백 함수를 등록할 수 있습니다.

주요 Expat 파서 함수:

  • xml_parser_create(): 새로운 XML 파서를 생성.
  • xml_set_element_handler(): XML 요소의 시작 및 종료 태그에 대한 처리 함수를 등록.
  • xml_set_character_data_handler(): XML 텍스트 데이터에 대한 처리 함수를 등록.
  • xml_parse(): XML 데이터를 파싱.
  • xml_parser_free(): 파서를 해제하여 메모리 사용을 줄임.

2. Expat으로 XML 파싱 예시

예시: XML 파일 파싱 및 처리

XML 파일 (example.xml)

<users>
    <user>
        <id>1</id>
        <name>John Doe</name>
        <email>john@example.com</email>
    </user>
    <user>
        <id>2</id>
        <name>Jane Doe</name>
        <email>jane@example.com</email>
    </user>
</users>

Expat 파서를 사용하여 XML 데이터 파싱

<?php
// XML 파서 생성
$parser = xml_parser_create();

// 시작 태그와 종료 태그 처리 함수 설정
xml_set_element_handler($parser, "startElement", "endElement");

// 텍스트 데이터 처리 함수 설정
xml_set_character_data_handler($parser, "characterData");

// XML 파일 로드
$xmlData = file_get_contents('example.xml');

// XML 파싱 시작
if (!xml_parse($parser, $xmlData, true)) {
    die(sprintf("XML Error: %s at line %d",
        xml_error_string(xml_get_error_code($parser)),
        xml_get_current_line_number($parser)));
}

// 파서 해제
xml_parser_free($parser);

// 시작 태그 처리 함수
function startElement($parser, $name, $attrs) {
    echo "Start tag: $name<br>";
}

// 종료 태그 처리 함수
function endElement($parser, $name) {
    echo "End tag: $name<br>";
}

// 텍스트 데이터 처리 함수
function characterData($parser, $data) {
    // 공백을 제거한 텍스트 데이터만 출력
    $data = trim($data);
    if (!empty($data)) {
        echo "Character data: $data<br>";
    }
}
?>

설명:

  • xml_parser_create(): XML 파서를 생성합니다.
  • xml_set_element_handler(): XML 요소의 시작 태그와 종료 태그를 처리할 함수를 등록합니다.
  • xml_set_character_data_handler(): XML 요소 사이의 텍스트 데이터를 처리할 함수를 등록합니다.
  • xml_parse(): XML 데이터를 파싱하며, 이벤트를 발생시킵니다.
  • 콜백 함수: XML 요소의 시작, 종료, 텍스트 데이터를 처리하는 사용자 정의 함수가 필요합니다.

3. Expat 파서 콜백 함수 설명

Expat 파서에서 XML 데이터를 처리하려면 콜백 함수를 통해 시작 태그, 종료 태그, 텍스트 데이터를 다룹니다.

3.1 시작 태그 처리 함수

function startElement($parser, $name, $attrs) {
    echo "Start tag: $name<br>";
}

  • $name: 시작된 태그 이름을 나타냅니다.
  • $attrs: 해당 태그의 속성(있을 경우)을 배열로 전달받습니다.

3.2 종료 태그 처리 함수

function endElement($parser, $name) {
    echo "End tag: $name<br>";
}

  • $name: 종료된 태그 이름을 나타냅니다.

3.3 텍스트 데이터 처리 함수

function characterData($parser, $data) {
    $data = trim($data);  // 공백 제거
    if (!empty($data)) {
        echo "Character data: $data<br>";
    }
}

  • $data: XML 요소 사이에 있는 텍스트 데이터를 전달받습니다.
  • 텍스트 데이터를 가져올 때 공백이 포함될 수 있으므로, 이를 trim() 함수로 제거하고 처리합니다.

4. 속성을 가진 XML 처리

Expat 파서를 사용하여 XML 속성도 처리할 수 있습니다. 속성은 배열 형태로 전달되며, 이를 통해 속성 값을 읽을 수 있습니다.

예시: 속성을 가진 XML 데이터 처리

XML 파일 (example_with_attributes.xml)

<users>
    <user id="1">
        <name>John Doe</name>
        <email>john@example.com</email>
    </user>
    <user id="2">
        <name>Jane Doe</name>
        <email>jane@example.com</email>
    </user>
</users>

속성 처리 코드

<?php
// XML 파서 생성
$parser = xml_parser_create();

// 시작 태그 처리 함수에 속성 처리 추가
xml_set_element_handler($parser, "startElement", "endElement");

// 텍스트 데이터 처리 함수 설정
xml_set_character_data_handler($parser, "characterData");

// XML 파일 로드
$xmlData = file_get_contents('example_with_attributes.xml');

// XML 파싱
if (!xml_parse($parser, $xmlData, true)) {
    die(sprintf("XML Error: %s at line %d",
        xml_error_string(xml_get_error_code($parser)),
        xml_get_current_line_number($parser)));
}

// 파서 해제
xml_parser_free($parser);

// 시작 태그 처리 함수 (속성 포함)
function startElement($parser, $name, $attrs) {
    echo "Start tag: $name<br>";
    if (!empty($attrs)) {
        foreach ($attrs as $key => $value) {
            echo " - Attribute: $key = $value<br>";
        }
    }
}

// 종료 태그 처리 함수
function endElement($parser, $name) {
    echo "End tag: $name<br>";
}

// 텍스트 데이터 처리 함수
function characterData($parser, $data) {
    $data = trim($data);
    if (!empty($data)) {
        echo "Character data: $data<br>";
    }
}
?>

설명:

  • $attrs: 시작 태그 처리 함수에서 XML 요소의 속성 값을 배열 형태로 전달받습니다.
  • 속성 값을 반복문으로 출력하여 각 속성의 이름과 값을 처리합니다.

5. 큰 XML 파일 처리

Expat 파서는 이벤트 기반 파서이므로 대용량 XML 파일을 처리할 때 유리합니다. 한 번에 전체 XML 파일을 메모리에 로드하지 않고, 순차적으로 데이터를 처리하기 때문에 메모리 사용을 줄일 수 있습니다.

예시: 큰 XML 파일에서 데이터 처리

<?php
// XML 파서 생성
$parser = xml_parser_create();

// XML 파일을 스트림으로 읽기
$file = fopen('large_example.xml', 'r');

// 이벤트 핸들러 설정
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "characterData");

// 스트림에서 데이터를 반복적으로 읽고 파싱
while ($data = fread($file, 4096)) {
    if (!xml_parse($parser, $data, feof($file))) {
        die(sprintf("XML Error: %s at line %d",
            xml_error_string(xml_get_error_code($parser)),
            xml_get_current_line_number($parser)));
    }
}

// 파일 닫기 및 파서 해제
fclose($file);
xml_parser_free($parser);
?>

설명:

  • 스트림 읽기: fread()를 사용하여 XML 데이터를 한 번에 조금씩 읽어들이고, xml_parse()로 파싱합니다.
  • 이 방식은 대용량 XML 파일을 처리할 때 메모리 효율적입니다.

6. Expat 파서 오류 처리

XML 파일을 파싱할 때 발생할 수 있는 오류를 처리하는 것이 중요합니다. Expat 파서는 XML 구문에 오류가 있을 경우, 오류 메시지를 반환할 수 있습니다.

예시: XML 파서 오류 처리

<?php
// XML 파서 생성
$parser = xml_parser_create();

// XML 데이터 로

드
$xmlData = '<user><name>John Doe</name><email>john@example.com';  // 잘못된 XML

// XML 파싱 및 오류 확인
if (!xml_parse($parser, $xmlData, true)) {
    echo sprintf("XML Error: %s at line %d",
        xml_error_string(xml_get_error_code($parser)),
        xml_get_current_line_number($parser));
}

// 파서 해제
xml_parser_free($parser);
?>

설명:

  • xml_error_string(): XML 파싱 중 발생한 오류의 설명을 반환합니다.
  • xml_get_error_code(): 현재 발생한 오류 코드를 반환합니다.
  • xml_get_current_line_number(): 오류가 발생한 XML 파일의 라인 번호를 반환합니다.

7. 보안 고려 사항

7.1 외부 엔티티 주입(XML External Entity, XXE) 방지

XML 파일을 처리할 때, 외부 엔티티 주입(XXE) 공격에 주의해야 합니다. Expat 파서는 기본적으로 외부 엔티티를 지원하지 않지만, XML 데이터를 처리할 때는 항상 입력 데이터의 유효성을 확인해야 합니다.

7.2 입력 데이터 유효성 검사

XML 데이터를 다룰 때는 사용자 입력 또는 외부 데이터에 대한 유효성 검사를 수행하여 안전성을 보장하는 것이 중요합니다.


요약

PHP의 Expat XML 파서이벤트 기반 파서로, XML 파일을 순차적으로 처리하며 태그 시작, 종료, 텍스트 데이터를 이벤트로 처리할 수 있습니다. 대용량 XML 파일을 처리하는 데 적합하며, 메모리 사용을 줄일 수 있습니다. Expat 파서를 사용하면 XML 요소, 속성, 텍스트 데이터를 효율적으로 처리할 수 있으며, 콜백 함수를 통해 XML 데이터에 대한 구체적인 처리를 구현할 수 있습니다. XML 처리 중 오류 처리보안을 고려하는 것이 중요합니다.


copyright ⓒ 스타트코딩 all rights reserved.
이메일 : startcodingim@gamil.com