PHP로 XML을 읽고 쓰는 데는 다양한 기술이 있습니다. 이 기사에서는 XML을 읽는 세 가지 방법, 즉 DOM 라이브러리 사용, SAX 파서 사용 및 정규식 사용을 제공합니다. DOM 및 PHP 텍스트 템플릿을 사용하여 XML을 작성하는 방법도 다룹니다.
PHP에서 XML(Extensible Markup Language)을 읽고 쓰는 것은 조금 무섭게 느껴질 수 있습니다. 실제로 XML과 관련된 모든 기술은 두려울 수 있지만 PHP에서 XML을 읽고 쓰는 것이 두려운 작업일 필요는 없습니다. 먼저 XML이 무엇인지, XML로 무엇을 할 수 있는지에 대해 조금 배워야 합니다. 그런 다음 PHP에서 XML을 읽고 쓰는 방법을 배워야 하며 이를 수행하는 방법에는 여러 가지가 있습니다.
이 기사에서는 XML에 대한 간략한 소개를 제공하고 PHP로 XML을 읽고 쓰는 방법을 설명합니다.
XML이란 무엇입니까?
XML은 데이터 저장 형식입니다. 어떤 데이터가 저장되는지 정의하지 않으며 데이터 형식도 정의하지 않습니다. XML은 단순히 태그와 해당 태그의 속성을 정의합니다. 올바른 형식의 XML 마크업은 다음과 같습니다.
<이름>잭 헤링턴</name>
이 <name> 태그에는 Jack Herrington이라는 텍스트가 포함되어 있습니다.
텍스트가 없는 XML 마크업은 다음과 같습니다.
<파워업/>
XML로 무언가를 작성하는 방법은 여러 가지가 있습니다. 예를 들어 이 태그는 이전 태그와 동일한 출력을 형성합니다.
<파워업></파워업>
XML 태그에 속성을 추가할 수도 있습니다. 예를 들어, 이 <name> 태그에는 첫 번째 속성과 마지막 속성이 포함되어 있습니다.
<이름 첫 번째="잭" 마지막="헤링턴" />
특수 문자는 XML로 인코딩될 수도 있습니다. 예를 들어 & 기호는 다음과 같이 인코딩될 수 있습니다.
&
태그와 속성이 포함된 XML 파일은 예제와 같은 형식이면 형식 이 올바른 것 입니다. 즉, 태그가 대칭이고 문자가 올바르게 인코딩되었음을 의미합니다. 목록 1은 올바른 형식의 XML의 예입니다.
목록 1. XML 도서 목록 예
〈책〉
<책>
<저자>잭 헤링턴</저자>
<title>PHP 해킹</title>
<출판사>오라일리</publisher>
</book>
<책>
<저자>잭 헤링턴</저자>
<title>팟캐스팅 해킹<//title>
<출판사>오라일리</publisher>
</book>
</books>
|
목록 1의 XML에는 책 목록이 포함되어 있습니다. 상위 <books> 태그에는 <book> 태그 세트가 포함되어 있으며 각 태그에는 <author>, <title> 및 <publisher> 태그가 포함되어 있습니다.
외부 스키마 파일을 통해 마크업 구조와 콘텐츠가 확인되면 XML 문서는 올바른 것입니다. 스키마 파일은 다양한 형식으로 지정할 수 있습니다. 이 기사에서는 올바른 형식의 XML만 있으면 됩니다.
XML이 HTML(Hypertext Markup Language)과 매우 유사하다고 생각하신다면 맞습니다. XML과 HTML은 모두 마크업 기반 언어이며 많은 유사점을 가지고 있습니다. 그러나 XML 문서는 올바른 형식의 HTML일 수 있지만 모든 HTML 문서가 올바른 형식의 XML은 아니라는 점을 지적하는 것이 중요합니다. 개행 태그(br)는 XML과 HTML의 차이점을 보여주는 좋은 예입니다. 이 개행 태그는 올바른 형식의 HTML이지만 올바른 형식의 XML은 아닙니다.
<p>문단입니다<br>
줄바꿈 있음</p>
이 개행 태그는 올바른 형식의 XML 및 HTML입니다.
<p>문단입니다<br />
줄바꿈 있음</p>
HTML을 올바른 형식의 XML로 작성하려면 W3C 위원회의 XHTML(Extensible Hypertext Markup Language) 표준을 따르십시오(참고 자료 참조). 모든 최신 브라우저는 XHTML을 렌더링할 수 있습니다. 게다가 XML 도구를 사용하면 XHTML을 읽고 문서에서 데이터를 찾을 수 있는데, 이는 HTML을 구문 분석하는 것보다 훨씬 쉽습니다.
DOM 라이브러리를 사용하여 XML 읽기
올바른 형식의 XML 파일을 읽는 가장 쉬운 방법은 일부 PHP 설치에 컴파일된 DOM(문서 개체 모델) 라이브러리를 사용하는 것입니다. DOM 라이브러리는 전체 XML 문서를 메모리로 읽어 들여 그림 1과 같이 노드 트리로 표시합니다.
그림 1. 책 XML을 위한 XML DOM 트리
트리 상단의 books 노드에는 두 개의 book 하위 태그가 있습니다. 각 책에는 저자, 출판사, 제목 등 여러 노드가 있습니다. 작성자, 출판사 및 제목 노드에는 각각 텍스트가 포함된 텍스트 하위 노드가 있습니다.
책 XML 파일을 읽고 DOM을 사용하여 콘텐츠를 표시하는 코드는 목록 2에 표시됩니다.
목록 2. DOM을 사용하여 책 XML 읽기
<?php
$doc = 새로운 DOMDocument();
$doc->load( 'books.xml' );
$books = $doc->getElementsByTagName( "책" );
foreach($books를 $book으로)
{
$authors = $book->getElementsByTagName( "저자" );
$author = $authors->item(0)->nodeValue;
$publishers = $book->getElementsByTagName( "출판사" );
$publisher = $publishers->item(0)->nodeValue;
$titles = $book->getElementsByTagName( "제목" );
$title = $titles->항목(0)->nodeValue;
echo "$title - $author - $publishern";
}
?>
|
스크립트는 먼저 새 DOMdocument 객체를 생성하고 load 메소드를 사용하여 책 XML을 이 객체에 로드합니다. 그런 다음 스크립트는 getElementsByName 메소드를 사용하여 지정된 이름 아래의 모든 요소 목록을 가져옵니다.
책 노드의 루프에서 스크립트는 getElementsByName 메소드를 사용하여 저자, 출판사 및 제목 태그의 nodeValue를 얻습니다. nodeValue는 노드의 텍스트입니다. 그런 다음 스크립트는 이러한 값을 표시합니다.
다음과 같이 명령줄에서 PHP 스크립트를 실행할 수 있습니다.
%phpe1.php
PHP 해킹 - Jack Herrington - O'Reilly
팟캐스팅 해킹 - Jack Herrington - O'Reilly
%
보시다시피 각 책 블록은 한 줄을 출력합니다. 이것은 좋은 시작입니다. 하지만 XML DOM 라이브러리에 액세스할 수 없다면 어떻게 될까요?
SAX 파서로 XML 읽기
XML을 읽는 또 다른 방법은 SAX(XML Simple API) 파서를 사용하는 것입니다. 대부분의 PHP 설치에는 SAX 파서가 포함되어 있습니다. SAX 파서는 콜백 모델에서 실행됩니다. 태그가 열리거나 닫힐 때마다 또는 파서가 텍스트를 볼 때마다 사용자 정의 함수는 노드 또는 텍스트에 대한 정보와 함께 호출됩니다.
SAX 파서의 장점은 정말 가볍다는 것입니다. 파서는 오랜 기간 동안 콘텐츠를 메모리에 보관하지 않으므로 매우 큰 파일에 사용할 수 있습니다. 단점은 SAX 파서 콜백 작성이 매우 번거롭다는 것입니다. 목록 3은 SAX를 사용하여 책 XML 파일을 읽고 콘텐츠를 표시하는 코드를 보여줍니다.
목록 3. SAX 구문 분석기를 사용하여 책 XML 읽기
<?php
$g_books = 배열();
$g_elem = null;
함수 startElement( $parser, $name, $attrs )
{
글로벌 $g_books, $g_elem;
if ( $name == 'BOOK' ) $g_books []= array();
$g_elem = $이름;
}
함수 endElement( $parser, $name )
{
글로벌 $g_elem;
$g_elem = null;
}
함수 텍스트데이터( $parser, $text )
{
글로벌 $g_books, $g_elem;
if ( $g_elem == 'AUTHOR' ||
$g_elem == '출판사' ||
$g_elem == '제목' )
{
$g_books[ 개수( $g_books ) - 1 ][ $g_elem ] = $text;
}
}
$parser = xml_parser_create();
xml_set_element_handler( $parser, "startElement", "endElement" );
xml_set_character_data_handler( $parser, "textData" );
$f = fopen( 'books.xml', 'r' );
while( $data = fread( $f, 4096 ) )
{
xml_parse( $parser, $data );
}
xml_parser_free( $parser );
foreach($g_books를 $book으로)
{
echo $book['TITLE']." - ".$book['AUTHOR']." - ";
echo $book['PUBLISHER']."n";
}
?>
|
스크립트는 먼저 모든 책과 책 정보를 메모리에 보유하는 g_books 배열을 설정하고 g_elem 변수는 스크립트가 현재 처리 중인 태그의 이름을 보유합니다. 그런 다음 스크립트는 콜백 함수를 정의합니다. 이 예에서 콜백 함수는 startElement, endElement 및 textData입니다. 마크를 열고 닫을 때 각각 startElement 및 endElement 함수를 호출합니다. TextData는 여는 태그와 닫는 태그 사이의 텍스트에서 호출됩니다.
이 예에서 startElement 태그는 book 태그를 찾아 book 배열에서 새 요소를 시작합니다. 그런 다음 textData 함수는 현재 요소를 조사하여 게시자, 제목 또는 작성자 태그인지 확인합니다. 그렇다면 함수는 현재 텍스트를 현재 책에 넣습니다.
계속해서 구문 분석을 허용하기 위해 스크립트는 xml_parser_create 함수를 사용하여 구문 분석기를 생성합니다. 그런 다음 콜백 핸들을 설정합니다. 그런 다음 스크립트는 파일을 읽고 파일 청크를 파서로 보냅니다. 파일을 읽은 후 xml_parser_free 함수는 파서를 제거합니다. 스크립트의 끝은 g_books 배열의 내용을 출력합니다.
보시다시피 이는 DOM에 동일한 기능을 작성하는 것보다 훨씬 더 어렵습니다. DOM 라이브러리도 없고 SAX 라이브러리도 없으면 어떻게 되나요? 대안이 있나요?
정규식을 사용하여 XML 구문 분석
일부 엔지니어는 이 방법을 언급한 것 때문에 나를 비난할 것이라고 확신하지만 정규식을 사용하여 XML을 구문 분석하는 것이 가능합니다. Listing 4에서는 preg_ 함수를 사용하여 책 파일을 읽는 예를 보여줍니다.
목록 4. 정규식을 사용하여 XML 읽기
<?php
$xml = "";
$f = fopen( 'books.xml', 'r' );
while( $data = fread( $f, 4096 ) ) { $xml .= $data }
fclose( $f );
preg_match_all( "/<책>(.*?)</book>/s",
$xml, $bookblocks );
foreach( $bookblocks[1] 를 $block 으로)
{
preg_match_all( "/<작성자>(.*?)</작성자>/",
$block, $author );
preg_match_all( "/<제목>(.*?)</제목>/",
$block, $title );
preg_match_all( "/<게시자>(.*?)</publisher>/",
$block, $publisher );
echo( $title[1][0]." - ".$author[1][0]." - ".
$publisher[1][0]."n" );
}
?>
|
이 코드가 얼마나 짧은지 확인하세요. 처음에는 파일을 큰 문자열로 읽습니다. 그런 다음 정규식 함수를 사용하여 각 책 항목을 읽습니다. 마지막으로 foreach 루프를 사용하여 각 책 블록을 반복하고 저자, 제목 및 출판사를 추출합니다.
그렇다면 결함은 어디에 있습니까? 정규식 코드를 사용하여 XML을 읽을 때의 문제점은 XML이 올바른 형식인지 먼저 확인하지 않는다는 것입니다. 즉, XML을 읽기 전에는 XML의 형식이 올바른지 알 수 있는 방법이 없습니다. 또한 일부 올바른 형식의 XML은 정규식과 일치하지 않을 수 있으므로 나중에 수정해야 합니다.
XML을 읽을 때 정규식을 사용하는 것은 결코 권장되지 않지만 정규식 함수를 항상 사용할 수 있기 때문에 때로는 정규식을 사용하는 것이 호환성을 위한 최선의 방법입니다. XML의 형식이나 구조를 제어할 수 없으므로 정규식을 사용하여 사용자로부터 직접 XML을 읽지 마십시오. 사용자로부터 XML을 읽으려면 항상 DOM 라이브러리나 SAX 파서를 사용해야 합니다. DOM을 사용하여 XML 작성
XML을 읽는 것은 방정식의 일부일뿐입니다. XML을 작성하는 방법? XML을 작성하는 가장 좋은 방법은 DOM을 사용하는 것입니다. Listing 5에서는 DOM이 책 XML 파일을 빌드하는 방법을 보여줍니다.
목록 5. DOM을 사용하여 책 XML 작성
<?php
$책 = 배열();
$books [] = 배열(
'제목' => 'PHP 해킹',
'저자' => '잭 헤링턴',
'출판사' => "오라일리"
);
$books [] = 배열(
'제목' => '팟캐스팅 해킹',
'저자' => '잭 헤링턴',
'출판사' => "오라일리"
);
$doc = 새로운 DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "책" );
$doc->appendChild( $r );
foreach($books를 $book으로)
{
$b = $doc->createElement( "책" );
$author = $doc->createElement( "저자" );
$author->appendChild(
$doc->createTextNode( $book['author'] )
);
$b->appendChild( $author );
$title = $doc->createElement( "제목" );
$title->appendChild(
$doc->createTextNode( $book['제목'] )
);
$b->appendChild( $제목 );
$publisher = $doc->createElement( "게시자" );
$publisher->appendChild(
$doc->createTextNode( $book['publisher'] )
);
$b->appendChild($publisher);
$r->appendChild( $b );
}
echo $doc->saveXML();
?>
|
스크립트 상단에는 일부 샘플 책이 포함된 books 배열이 로드됩니다. 이 데이터는 사용자 또는 데이터베이스에서 가져올 수 있습니다.
샘플 책이 로드된 후 스크립트는 새 DOMDocument를 생성하고 여기에 루트 책 노드를 추가합니다. 그런 다음 스크립트는 각 책의 저자, 제목 및 출판사에 대한 노드를 생성하고 각 노드에 텍스트 노드를 추가합니다. 각 책 노드의 마지막 단계는 이를 루트 노드 책에 다시 추가하는 것입니다.
스크립트 끝에서 saveXML 메서드를 사용하여 XML을 콘솔에 출력합니다. (save 메소드를 사용하여 XML 파일을 작성할 수도 있습니다.) 스크립트의 출력은 목록 6에 표시됩니다.
목록 6. DOM 빌드 스크립트의 출력
%phpe4.php
<?xml 버전="1.0"?>
〈책〉
<책>
<저자>잭 헤링턴</저자>
<title>PHP 해킹</title>
<출판사>오라일리</publisher>
</book>
<책>
<저자>잭 헤링턴</저자>
<title>팟캐스팅 해킹<//title>
<출판사>오라일리</publisher>
</book>
</books>
%
|
DOM 사용의 실제 가치는 DOM이 생성하는 XML이 항상 올바른 형식이라는 것입니다. 하지만 DOM을 사용하여 XML을 만들 수 없다면 어떻게 될까요?
PHP로 XML 작성
DOM을 사용할 수 없는 경우 PHP의 텍스트 템플릿을 사용하여 XML을 작성할 수 있습니다. 목록 7은 PHP가 책 XML 파일을 빌드하는 방법을 보여줍니다.
목록 7. PHP로 책 XML 작성
<?php
$책 = 배열();
$books [] = 배열(
'제목' => 'PHP 해킹',
'저자' => '잭 헤링턴',
'출판사' => "오라일리"
);
$books [] = 배열(
'제목' => '팟캐스팅 해킹',
'저자' => '잭 헤링턴',
'출판사' => "오라일리"
);
?>
〈책〉
<?php
foreach($books를 $book으로)
{
?>
<책>
<제목><?php echo( $book['제목'] ?></제목>
<저자><?php echo( $book['author'] ?>
</저자>
<출판사><?php echo( $book['publisher'] ?>
</출판사>
</book>
<?php
}
?>
</books>
|
스크립트의 상단 부분은 DOM 스크립트와 유사합니다. 스크립트 하단에서는 책 태그를 연 다음 각 책을 반복하여 책 태그와 모든 내부 제목, 저자 및 출판사 태그를 생성합니다.
이 접근 방식의 문제점은 엔터티를 인코딩하는 것입니다. 엔터티가 올바르게 인코딩되었는지 확인하려면 목록 8에 표시된 대로 각 항목에 대해 htmlentities 함수를 호출해야 합니다.
목록 8. htmlentities 함수를 사용하여 엔터티 인코딩
〈책〉
<?php
foreach($books를 $book으로)
{
$title = htmlentities( $book['title'], ENT_QUOTES );
$author = htmlentities( $book['author'], ENT_QUOTES );
$publisher = htmlentities( $book['publisher'], ENT_QUOTES );
?>
<책>
<제목><?php echo( $title ) ?></제목>
<저자><?php echo( $author ) </저자>
<퍼블리셔><?php echo( $publisher ?>
</출판사>
</book>
<?php
}
?>
</books>
|
이것이 바로 기본 PHP에서 XML을 작성하는 것이 짜증나는 부분입니다. 완벽한 XML을 만들었다고 생각하지만 데이터를 사용하려고 하면 일부 요소가 잘못 인코딩되었음을 발견하게 됩니다.
결론
XML을 둘러싼 과장과 혼란은 항상 많습니다. 그러나 생각만큼 어렵지는 않습니다. 특히 PHP와 같은 훌륭한 언어에서는 더욱 그렇습니다. XML을 올바르게 이해하고 구현하면 사용할 수 있는 강력한 도구를 많이 찾을 수 있습니다. XPath와 XSLT는 연구할 가치가 있는 두 가지 도구입니다.