ajax로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

ajax로 검색한 결과
등록일:2008-04-02 15:13:28
작성자:
제목:PHP에서 풀(pull) 방식으로 XML 구문을 분석하는 방법 (한글)


스트리밍 방식으로 메모리 효율을 높인다

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

수평출력으로 설정

이 페이지 출력

이 페이지를 이메일로 보내기

이 페이지를 이메일로 보내기

영어원문

영어원문


제안 및 의견
피드백

난이도 : 중급

Elliotte Harold, 교수, Polytechnic University

2008 년 3 월 11 일

여기서는 PHP 5부터 추가된 XMLReader 라이브러리를 소개합니다. XMLReader 라이브러리를 사용하면 PHP에서 효율적인 스트리밍 모드로 XML 문서를 처리할 수 있습니다.

2008년 1월 11일에 개정한 내용: 구문분석기 초기화와 문서 읽어들이기에서 세 번째 코드를 $reader->XML('http://www.cafeaulait.org/today.atom');에서 $reader->open('http://www.cafeaulait.org/today.atom');으로 변경했다.

PHP 5는 XML(eXtensible Markup Language)을 읽는 클래스인 XMLReader를 새롭게 지원한다. SimpleXML이나 DOM(Document Object Model)과는 달리 XMLReader는 스트리밍 모드에서 동작한다. 즉, 문서를 처음부터 끝까지 읽어들인다는 뜻이다. 또한 문서를 끝까지 읽기 전에 이미 읽어들인 부분만으로도 작업이 가능하다. 따라서 속력이 매우 빠르고, 효율성이 높으며, 메모리가 크게 절약된다. 처리할 문서가 클수록 메모리 효율과 속력은 더욱 중요한 요인이다.

libxml

여기서 소개하는 XMLReader API는 Gnome 프로젝트의 C/C++용 libxml 라이브러리를 사용한다. 구체적으로 보면 libxml의 XmlTextReader API를 호출하는 PHP 레이어일 뿐이다. XmlTextReader는 .NET의 XmlTextReaderXmlReader 클래스를 모델로 삼았다(코드를 공유하지는 않는다).

푸시(push) 모델을 사용하는 SAX(Simple API for XML)와는 달리, XMLReader는 풀(pull) 모델을 사용하는 구문분석기다. 즉, 여러분이 만든 프로그램에 통제권이 있다는 뜻이다. 구체적으로 설명하자면, 구문분석기가 프로그램으로 이벤트를 밀어주는 방식이 아니라, 프로그램에서 다음 이벤트를 명시적으로 가져오는 방식이다. 프로그램이 발생하는 이벤트에 반응하기보다 프로그램에서 내용을 요청한다고 보면 된다. 디자인 패턴 관점에서 보면, XMLReader는 Observer 패턴이 아니라 Iterator 패턴을 구현한 클래스라고 하겠다.

간단한 예제

먼 저 간단한 예제를 살펴보자. XML-RPC 요청을 받아서 응답을 보내는 PHP 스크립트를 구현하려고 한다. 좀더 구체적으로 설명하면, 우리의 예제 프로그램은 Listing 1과 같은 XML-PRC 요청을 받는다. 요청에서 루트 요소는 methodCall이고, methodCallmethodNameparams라는 요소를 포함한다. 메서드 이름은 sqrt다. params 요소는 param 하나를 포함하는데, 이는 제곱근을 구할 double 값이다. 이름 공간(namespace)은 사용하지 않는다.


Listing 1. XML-RPC 요청
                
<?xml version="1.0"?>
<methodCall>
<methodName>sqrt</methodName>
<params>
<param>
<value><double>36.0</double></value>
</param>
</params>
</methodCall>

PHP 스크립트가 할 일은 다음과 같다.

  1. 메서드 이름을 확인한다. 메서드 이름이 sqrt가 아니면 fault를 반환한다(스크립트는 sqrt 밖에 처리할 줄 모른다).
  2. 인수를 찾는다. 인수가 없거나 유형이 올바르지 않으면 falut를 반환한다.
  3. 그렇지 않으면 제곱근을 계산한다.
  4. 결과를 Listing 2와 같은 형태로 반환한다.

Listing 2. XML-RPC 응답
                
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><double>6.0</double></value>
</param>
</params>
</methodResponse>

이제 단계적으로 코드를 구현해 보자.




위로


구문분석기 초기화와 문서 읽어들이기

첫 번째 단계로 새 구문분석기 개체를 생성한다. 방법은 간단하다.

$reader = new XMLReader();

다음으로 구문분석기에 구문을 분석할 자료를 넘긴다. XML-RPC에서는 HTTP 요청이 여기에 해당한다. 다음과 같이 reader의 XML() 함수에 HTTP 요청 전체를 그대로 넘긴다.

원시 포스트 데이터 채우기

$HTTP_RAW_POST_DATA가 비어 있으면 php.ini 파일에 다음 행을 추가한다.

always_populate_raw_post_data = On

$request = $HTTP_RAW_POST_DATA;
$reader->XML($request);

어떤 문자열이라도 구문 분석이 가능하다. 프로그램 내에서 문자열을 지정해도 괜찮고, 로컬 파일에서 읽어들여도 괜찮다. open() 함수로 외부 URL에서 데이터를 가져와도 상관이 없다. 예를 들어, Atom 피드에서 자료를 가져오려면 다음 방법을 사용한다.

$reader->open('http://www.cafeaulait.org/today.atom');

어디서 데이터를 가져왔든 reader는 이제 구문을 분석할 준비가 되었다.




위로


문서 읽기

read() 함수는 구문분석기를 다음 토큰까지 전진시킨다. 문서를 읽는 가장 간단한 방법은 while 루프다.

while ($reader->read()) {
// processing code goes here...
}

문서를 다 읽은 후에는 구문분석기를 닫아서 자원을 해제하고 다음 문서 처리를 위해 상태를 재설정한다.

$reader->close();

루프 안에서 구문분석기는 요소 시작, 요소 끝, 텍스트 노드, 주석 등 특정한 노드에서 멈춘다. 현재 구문분석기가 위치한 지점을 알아내려면 다음 속성을 확인한다.

  • localName은 노드 로컬 이름으로 접두어가 붙지 않는다.
  • name은 노드 이름이다. 접두어가 붙기도 한다. 주석처럼 이름이 없는 노드는 DOM처럼 #comment, #text, #document 등과 같은 값을 갖는다.
  • namespaceURI는 노드 이름 공간의 URI(Uniform Resource Identifier)다.
  • nodeType은 노드 유형을 뜻하는 정수다. 예를 들어, 2는 속성 노드를 가리키고 7은 처리 명령을 가리킨다.
  • prefix는 노드의 이름 공간 접두어다.
  • value는 노드의 텍스트 내용이다.
  • hasValue는 노드에 텍스트 내용이 존재하는지 여부를 나타낸다.

물 론, 일부 속성 값이 없는 노드 유형도 존재한다. 예를 들어 텍스트 노드, CDATA 섹션, 주석, 처리 명령, 속성, 공백, 문서 유형, XML 선언부는 값이 존재한다. 다른 노드 유형, 특히 요소와 문서는 값이 존재하지 않는다. 일반적으로 프로그램을 짤 때는 nodeType을 살펴 노드 유형을 알아낸 후 적절히 처리해야 한다. Listing 3은 위 함수를 사용해 값을 출력하는 while 루프다. Listing 4는 Listing 3 reader에 Listing 1을 넘겨 얻은 결과다.


Listing 3. 구문분석기가 위치하는 값 출력하기
                
while ($reader->read()) {
echo $reader->name;
if ($reader->hasValue) {
echo ": " . $reader->value;
}
echo "\n";
}


Listing 4. Listing 3에 Listing 1을 넘겨 얻은 결과
                methodCall
#text:

methodName
#text: sqrt
methodName
#text:

params
#text:

param
#text:

value
double
#text: 10
double
value
#text:

param
#text:

params
#text:

methodCall

대다수 프로그램은 위 예제처럼 일반적이지 못하다. 대개는 특정한 형식을 입력 받아서 특정한 방식으로 처리한다. 우리 XML-PRC 예제에서는 double 요소 하나만 읽어들여야 한다. 또한 문서에는 double 요소가 단 하나만 존재해야 한다. 이를 수행하려면 이름이 double인 요소의 시작을 찾아야 한다.

if ($reader->name == "double"
&& $reader->nodeType == XMLReader::ELEMENT) {
// ...
}

이 요소는 십중팔구 텍스트 노드 자식이 하나이므로, 아래 코드와 같이 구문분석기를 다음 노드로 이동한다.

if ($reader->name == "double" && $reader->nodeType == XMLReader::ELEMENT) {
$reader->read();
respond($reader->value);
}

여기서 respond() 함수는 XML-PRC 응답을 작성하여 클라이언트에 반환한다. 그러나 이 함수를 살펴보기 전에 한 가지 짚고 넘어갈 사항이 있다. 위 예제에서 요청 문서에 double 요소가 정확히 텍스트 노드 하나라는 보장은 없다. 아래 예제처럼, 주석과 처리 명령 등 다른 노드를 포함할 가능성이 충분히 존재한다.

 <value><double>
<!--value follows-->6.<!--fractional part next-->0
</double></value>

중첩 요소

Listing 5 코드는 한 가지 잠재적인 결함이 존재한다. <double>6<double>1.2</double></double>처럼 중첩된 double 요소를 올바로 처리하지 못한다는 점이다. 하지만 유효한 XML-PRC 요청에서는 이러한 경우가 존재하지 않으며, 잠시 후 RELAX NG로 문법을 검증하여 잘못된 문서를 거부하는 방법을 소개한다. XHTML(eXtensible Hypertext Markup Language)과 같이 (table 내부에 table이 존재하는 등) 중첩 요소를 허용하는 문서에서는 요소 깊이를 추적하여 시작 태그 수와 끝 태구 수가 일치하는지도 확인해야 한다.

따라서 double 요소 내에서 모든 자식 텍스트 노드를 추출해 연결한 후 double로 변환하는 방법이 안전하다. 주석 등 텍스트 노드가 아닌 자식이 존재할지도 모르니 주의 깊게 피해야 한다. Listing 5에서 보듯이 다소 복잡하지만 크게 어려운 코드는 아니다.


Listing 5. 요소에서 모든 텍스트 내용 추출하여 연결하기
                
while ($reader->read()) {
if ($reader->nodeType == XMLReader::TEXT
|| $reader->nodeType == XMLReader::CDATA
|| $reader->nodeType == XMLReader::WHITESPACE
|| $reader->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
$input .= $reader->value;
}
else if ($reader->nodeType == XMLReader::END_ELEMENT
&& $reader->name == "double") {
break;
}
}

당장은 문서에서 double 외 다른 요소는 모두 무시한다(나중에 오류 처리 방법을 살펴보겠다).




위로


응답 작성

이름이 암시하듯이 XMLReader는 순전히 읽기용 클래스다. XMLReader에 상응하는 XMLWriter 클래스는 현재 개발 중이며 아직 나오지 않았다. 하지만 다행스럽게도 XML은 읽기보다 쓰기가 훨씬 쉬운 언어다. 우선 header() 함수로 응답 미디어 유형을 설정한다. XML-RPC에서는 아래와 같이 application/xml로 설정한다.

header('Content-type: application/xml');

Listing 6에서 보듯이 respond() 함수는 echo를 사용해 내용을 페이지에다 그대로 출력한다.


Listing 6. echo로 XML 출력
                 function respond($input) {

echo "<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><double>" .
sqrt($input)
. "</double></value>
</param>
</params>
</methodResponse>";

}

문자열 부분을(HTML 페이지에서처럼) PHP 페이지에 그대로 출력해도 좋다. Listing 7은 이 방법을 보여준다.


Listing 7. 그대로 XML 출력하기
                 function respond($input) {

?><?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><double>"<?php
echo sqrt($input);
?>
</double></value>
</param>
</params>
</methodResponse>
<?php
}




위로


오류 처리

지금까지는 문서가 형식이 갖춰진 형태(well-formed)라고 가정했다. 그러나 현실적으로 문서가 항상 형식을 갖추고 있다는 보장은 없다. 여느 XML 구문분석기와 마찬가지로, XMLReader 역시 형식을 깨는 구문 오류를 감지하는 순간 구문 분석을 중단한다. 이 때 read() 함수는 false를 반환한다.

이 론적으로는 구문분석기가 처음으로 오류를 발견한 지점까지 문서를 처리해야 마땅하다. 하지만 간단한 문서로 실험한 결과, 구문분석기는 오류를 거의 즉시 반환했다. 기반 구문분석기는 문서를 한꺼번에 읽어서 캐시에 저장한 후 한 번에 조금씩 처리한다. 그래서인지 오류를 성급하게 진단하는 경향이 보인다. 그러니 프로그램을 짤 때는 첫 번째 구문 오류가 발생하는 지점까지 문서를 분석할 수 있으리라 가정하지 않는 편이 안전하다. 또한 구문분석기가 문서를 분석하기 시작했다고 하여 문서에 구문 오류가 전혀 없다고 가정해서도 안 된다. 완벽하게 형식이 갖춰진 문서만 받아들이겠다면, 문서 끝을 확인할 때까지 복구 불가능한 작업을 수행하지 않는 편이 바람직하다.

구문분석기가 구문 오류를 감지하면 read() 함수는 다음과 같은 오류 메시지를 출력한다(아래는 verbose 모드에서 오류를 출력한 결과다. 개발 서버에서는 verbose 모드를 켜두는 편이 바람직하다).

<br />
<b>Warning</b>: XMLReader::read() [<a href='function.read'>function.read</a>]:
< value><double>10</double></value> in <b>/var/www/root.php</b>
on line <b>35</b><br />

위와 같은 오류를 HTML 페이지에 출력하면 사용자가 보게 된다. 이를 피하려면 $php_errormsg 환경 변수에다 오류 메시지를 저장한다. 그러려면 php.ini 파일에서 track_errors 구성 옵션을 켜야 한다.

track_errors = On

기본적으로 track_errors 옵션은 꺼져 있다. php.ini에 명시적으로 설정되어 있으니 해당 행에서 값을 변경해야 한다. 필자처럼 위 행을 php.ini 상단에 추가했다가는 나중에 나오는 track_errors = Off 행이 앞서 정의한 행을 덮어써버린다.

예제 프로그램은 완전하고 형식이 갖춰진 입력 문서에만 응답을 보낸다(물론 문서는 유효해야 한다. 유효성은 잠시 후에 다룬다). 따라서 구문 분석을 끝낼 때까지, 즉 while 루프를 빠져나올 때까지 기다려야 한다. 루프를 빠져나온 후에는 $php_errormsg에 오류 값이 있는지 확인한다. 오류가 없으면 문서가 정격(well-formed)이라는 뜻이므로 XML-PRC 응답을 보낸다. 오류가 있으면 문서가 형식을 갖추지 못했다는 뜻이므로 XML-RPC fault 응답을 보낸다. 또 누군가 음수의 제곱근을 요청할 때도 fault 응답을 보내야 한다. 코드는 Listing 8과 같다.


Listing 8. 형식이 갖춰졌는지 여부 검사
                
// set up the request
$request = $HTTP_RAW_POST_DATA;
error_reporting(E_ERROR | E_WARNING | E_PARSE);
if (isset($php_errormsg)) unset(($php_errormsg);
// create the reader
$reader = new XMLReader();
// $reader->setRelaxNGSchema("request.rng");
$reader->XML($request);

$input = "";
while ($reader->read()) {
if ($reader->name == "double" && $reader->nodeType == XMLReader::ELEMENT) {

while ($reader->read()) {
if ($reader->nodeType == XMLReader::TEXT
|| $reader->nodeType == XMLReader::CDATA
|| $reader->nodeType == XMLReader::WHITESPACE
|| $reader->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
$input .= $reader->value;
}
else if ($reader->nodeType == XMLReader::END_ELEMENT
&& $reader->name == "double") {
break;
}
}
break;
}
}

// make sure the input was well-formed
if (isset($php_errormsg) ) fault(21, $php_errormsg);
else if ($input < 0) fault(20, "Cannot take square root of negative number");
else respond($input);

위 코드는 스트리밍 모드에서 XML을 처리하는 일반적이고도 간단한 형식이다. 구문분석기는 문서를 처리한 후 필요한 자료 구조를 채운다. 대개 자료 구조는 문서 자체보다 간단하다. 여기서는 단지 문자열 하나만 채우면 된다.




위로


유효성 검사

libxml 버전

XMLReader가 사용하는 라이브러리인 libxml 초기 버전은 RELAX NG에 심각한 버그가 있었다. 따라서 사용 중인 버전이 적어도 2.06.26 이상인지 확인한다. 맥 OS X 타이거를 비롯하여 많은 시스템에서 버그가 많은 초기 버전을 제공한다.

지금까지는 다소 용감하게 자료가 특정 위치에 존재하리라 가정했다. 이 가정이 맞는지 손쉽게 판단하려면 문서가 스키마에 맞는지 검증하면 된다. XMLReader는 RELAX NG 스키마 언어를 지원한다. Listing 9는 예제 XML-PRC 요청이 따르는 RELAX NG 스키마를 보여준다.


Listing 9. XML-PRC 요청
                
<element name="methodCall" xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<element name="methodName">
<value>sqrt</value>
</element>
<element name="params">
<element name="param">
<element name="value">
<element name="double">
<data type="double"/>
</element>
</element>
</element>
</element>
</element>

setRelaxNGSchemaSource() 함수를 사용해 PHP 코드에다 스키마 문자열을 바로 입력해도 되고, setRelaxNGSchema() 함수를 사용하여 외부 파일이나 URL로 읽어와도 된다. Listing 9는 sqrt.rng라는 외부 파일에 저장된 스키마를 읽어오는 코드다.

reader->setRelaxNGSchema("sqrt.rng")

위 단계는 문서를 구문 분석하기 전에 수행해야 한다. 구문분석기가 문서를 읽으면서 문서와 스키마를 비교하기 때문이다. 문서가 유효한지 확인하려면 isValid() 함수를 호출한다. 이 함수는 호출 시점까지 문서가 유효하면 true를, 아니면 false를 반환한다. Listing 10은 구현을 끝낸 프로그램으로, 모든 오류 처리까지 포함한다. 정격이고 유효한 입력을 받아들여 올바른 값을 반환하며, 올바르지 ㅤㅇㅏㅎ은 요청을 모두 거부한다. 문제가 생겼을 때 XML-RPC fault를 응답하는 fault() 메서드를 추가했다.


Listing 10. 완성한 XML-PRC 제곱근 서버
                
<?php
header('Content-type: application/xml');

// try grammar
$schema = "<element name='methodCall'
xmlns='http://relaxng.org/ns/structure/1.0'
datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'>
<element name='methodName'>
<value>sqrt</value>
</element>
<element name='params'>
<element name='param'>
<element name='value'>
<element name='double'>
<data type='double'/>
</element>
</element>
</element>
</element>
</element>";


if (!isset($HTTP_RAW_POST_DATA)) {
fault(22, "Please make sure always_populate_raw_post_data = On in php.ini");
}
else {

// set up the request
$request = $HTTP_RAW_POST_DATA;
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// create the reader
$reader = new XMLReader();
$reader->setRelaxNGSchema("request.rng");
$reader->XML($request);

$input = "";
while ($reader->read()) {
if ($reader->name == "double" && $reader->nodeType == XMLReader::ELEMENT) {

while ($reader->read()) {
if ($reader->nodeType == XMLReader::TEXT
|| $reader->nodeType == XMLReader::CDATA
|| $reader->nodeType == XMLReader::WHITESPACE
|| $reader->nodeType == XMLReader::SIGNIFICANT_WHITESPACE) {
$input .= $reader->value;
}
else if ($reader->nodeType == XMLReader::END_ELEMENT
&& $reader->name == "double") {
break;
}
}
break;
}
}

if (isset($php_errormsg) ) fault(21, $php_errormsg);
else if (! $reader->isValid()) fault(19, "Invalid request");
else if ($input < 0) fault(20, "Cannot take square root of negative number");
else respond($input);

$reader->close();
}


function respond($input)
{
?>
<methodResponse>
<params>
<param>
<value><double><?php
echo sqrt($input);
?></double></value>
</param>
</params>
</methodResponse>
<?php
}


function fault($code, $message)
{

echo "<?xml version='1.0'?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>" . $code . "</int></value>
</member>
<member>
<name>faultString</name>
<value>
<string>" . $message . "</string>
</value>
</member>
</struct>
</value>
</fault>
</methodResponse>";

}




위로


속성

정상적인 풀 방식에서는 속성이 보이지 않는다. 속성을 읽으려면 요소 시작에서 멈춘 후 이름이나 숫자로 해당 속성을 요청해야 한다.

현재 요소에서 속성 값을 얻으려면 getAttribute() 함수에 원하는 속성 이름을 넘긴다. 예를 들어, 현재 요소의 id 속성을 얻으려면 다음 코드를 사용한다.

$id = $reader->getAttribute("id");

xlink:href처럼 속성이 이름 공간에 있는 경우에는 getAttributeNS() 함수를 사용한다. 함수로 넘기는 첫 번째 인수는 로컬 이름이고 두 번째 인수는 이름 공간 URI다(접두어는 중요하지 않다). 예를 들어, 다음 코드는 http://www.w3.org/1999/xlink/ 이름 공간에서 xlink:href 속성 값을 요청한다.

$href = $reader->getAttributeNS("href", "http://www.w3.org/1999/xlink/");

속성이 존재하지 ㅤㅇㅏㅎ으면 두 함수는 모두 빈 문자열을 반환한다(사실 이는 올바르지 못한 반환값이다. NULL을 반환해야 마땅하다. 현재 함수로는 속성 값이 비어 있는 경우와 속성이 존재하지 않는 경우를 구분하지 못한다).

속성 순서

XML 문서에서 속성 순서는 중요하지 않으며, 구문분석기 역시 속성 순서를 보존하지 않는다. 여기서 사용하는 숫자는 순전히 편의상 사용하는 색인 값이다. 시작 태그에서 첫 번째 속성은 속성 1, 두 번째 속성은 속성 2, 이렇게 순서대로 나간다는 보장은 없다. 속성 순서에 의존해 프로그램을 짜서는 안 된다.

만일 요소에 포함된 모든 속성을 알고 싶은데, 탐색에 앞서 이름은 모른다면, reader가 요소 위치에 도달할 때 moveToNextAttribute()를 호출한다. 일단 파서가 속성 노드에 위치하면 이름, 이름 공간, 요소를 위해 사용된 동일 속성값을 읽을 수 있다. 예를 들어, 다음 코드 조각은 현재 요소의 모든 속성을 출력한다.

  if ($reader->hasAttributes and $reader->nodeType == XMLReader::ELEMENT) {
while ($reader->moveToNextAttribute()) {
echo $reader->name . "='" . $reader->value . "'\n";
}
echo "\n";
}

XML API로서는 아주 드물게, XMLReader는 요소 시작과 끝에서 모두 속성을 읽을 수 있다. 같은 속성을 두 번 읽어들이지 않으려면 노드 유형이 XMLReader::END_ELEMENT가 아니라 XMLReader::ELEMENT인지 반드시 확인해야 한다.




위로


결론

소셜 북마크

mar.gar.in mar.gar.in
digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

XMLReader는 PHP 프로그래머 도구 상자에 추가할 만한 유용한 도구다. SimpleXML 확장과는 달리, 일부 문서가 아니라 모든 문서를 처리한다. DOM과는 달리, 가용 메모리 용량보다 더 큰 문서도 처리한다. SAX와는 달리, 프로그램에 통제권이 주어진다. PHP 프로그램에서 XML 문서를 입력 받아야 한다면 XMLReader를 고려하라고 적극 추천한다.



참고자료

교육
  • XMLReader를 위한 공식 문서: PHP 5 매뉴얼을 읽어보자.

  • PHP XMLReader 클래스: libxml의 C XMLReader API를 사용하는 PHP 클래스 매뉴얼

  • .NET의 ajax System.Xml.XmlTextReader: libxml의 XMLReader API가 모델로 삼은 클래스다.

  • XML in a Nutshell (Elliotte Rusty Harold and W. Scott Means, O'Reilly, 2005년): 얇지만 심도 있게 XML을 다루는 책이다. 두꺼운 소개서나 참조서 못지 않게 유용하다.

  • XML-RPC in Java programming(Roy Miller, developerWorks, 2004년 1월): 응용 프로그램 사이에 통신을 간단하게 수행하는 XML-RPC 서버/클라이언트 예제다.

  • PHP를 이용한 SimpleXML 프로세싱 (Elliotte Rusty Harold, developerWorks, 2006년 10월): SimpleXML 확장 기능을 사용하여 PHP로 XML 문서를 읽고 쓰는 방법을 소개한다.

  • Kicking back with RELAX NG, Part 1 (David Mertz, developerWorks, 2003년 2월 ): RELAX NG로 유효한 XML 인스턴스를 정의하는 클래스를 생성하는 강력하고, 정확하고, 이해하기 쉬운 방법을 소개한다.

  • Design Patterns (Addison-Wesley, 1995): 디자인 패턴을 심도 있게 소개하는 책으로, Observer와 Iterator 패턴을 자세히 살펴볼 수 있다.

  • IBM XML 인증: XML과 관련 기술 분야에서 IBM 인증 개발자가 되는 법을 알려준다.

  • XML 기술 라이브러리: 기사와 팁, 튜토리얼, 표준, IBM 레드북 등 다양한 기술 자료를 제공한다.

  • developerWorks 기술 이벤트와 웹 캐스트: 최신 기술 동향을 파악해 보라.


제품 및 기술 얻기

토론


필자소개


Elliotte Rusty Harold는 뉴 올리언즈 태생이다. 원조 검프 스프 맛을 찾아 뉴 올리언즈를 자주 방문하지만, 현재 브룩클린 근처 프로스펙트 하이츠에서 아내 베스와 고양이 두 마리를 키우며 폴리테크닉 대학 전자계산학과 조교수로 자바와 객체 지향 프로그래밍을 강의하고 있다. 그가 운영하는 Cafe au Lait 사이트는 인터넷에서 가장 인기 있는 자바 사이트 중 하나가 되었고, 또 다른 사이트 Cafe con Leche 역시 가장 대중적인 XML 사이트 중 하나가 되었다. 올 봄에는 애디슨 웨슬리 출판사를 통해 Refactoring HTML을 출판할 예정이다.