반응형

구조를 가진 데이터를 처리해야 하는 경우에 많이 사용되는이 "XML"이다. PHP에는 XML을 이용하기 위한 편리한 객체가 준비되어 있다. 그 사용법을 배우고 XML 데이터를 다뤄보기로 한다.


XML와 SimpleXML

PHP에는 XML을 처리하는 기능이 여러가지 준비되어 있다. PHP5 이전은 여러 함수를 호출하여 처리를 했지만, PHP5부터는 객체로 처리하는 방식이 추가되었다. 여기에서는 그 중 하나인 "SimpleXML"라는 기능을 이용하여 XML을 조작 해보자.

SimpleXML은 문자 그대로 XML을 이용하기 위한 아주 간단한 기능이다. 이는 XML 파일이나 텍스트에서 데이터를 읽어 들여, "SimpleXMLElement"라는 클래스의 인스턴스를 만든다. 이 오브젝트에 있는 메소드 등을 호출하여 XML 데이터를 처리한다.

XML 파일으로 객체를 생성한다

$변수 = simplexml_load_file(파일 지정);

텍스트 값에서 객체를 생성한다.

$변수 = simplexml_load_string(텍스트);

이 함수들은 첫번째 인수에 파일을 지정 (파일 이름이나 파일의 경로)하거나 XML 텍스트를 지정하여 객체를 만든다. 사실 이 함수들에는 인수가 더 준비되어 있는데, 우선 지정 데이터에서 XML 객체를 생성한다면 한개의 인수만 지정해되 된다.

또는 함수를 호출하여 방식이 아닌, 오브젝트인 SimpleXMLElement를 new로 만드는 방법도 있다. 이것도 인수가 몇개가 더 있지만, 우선 3개의 인수를 사용하는 방법은 아래와 같다.

SimpleXMLElement를 생성하기

$변수 = new SimpleXMLElement(데이터, 옵션, 부울);

첫번째 인수는 XML 데이터이다. 이는 XML 텍스트도 가능하고 XML 파일의 URL을 지정해도 된다. 두번째 인자인 옵션 값은 지정하는 것인데, 우선 0으로 지정한다. 0은 아무 옵션은 없을 경우의 값이다

세번째 인수의 부울는 첫번째 인수의 데이터 파일 여부를 지정한다. 첫번째 인수에 XML 텍스트를 지정하고 있는 경우는 false (또는 생략해도 좋다)이며, 파일의 URL을 지정하고 있다면 true로 한다. 파일에서 데이터를 가져오는 경우, 이 세번째 인수가 true로 설정되어 있지 않으면 객체 생성에 실패하기 때문에 반드시 지정을 해야 한다.

우선, 이제 XML 데이터를 처리하기 위한 SimpleXMLElement 개체를 만들 수 있게 되었다!

XML 파일 생성

그럼 XML을 조작하는 예제로 간단한 XML 데이터를 생성해 보자. 아래에 코드 샘플대로 작성하면 된다.

data.xml

<?xml version="1.0" encoding="UTF-8"?>
<datas>
    <data>
        <name>Windows</name>
        <version>9</version>
        <price>99</price>
    </data>
    <data>
        <name>Mac</name>
        <version>15</version>
        <price>99999</price>
    </data>
    <data>
        <name>Linux</name>
        <version>123.4567</version>
        <price>0</price>
    </data>
</datas>

이는 'data.xml'라는 파일명으로 PHP 파일 (index.php 등 이번 작성하게 될 파일)과 같은 위치에 배치해 둔다.

SimpleXMLElement의 데이터 얻기

SimpleXMLElement에는 다양한 메소드가 준비되어 있다. 그 메소드들을 이용하여 XML에서 필요한 정보를 얻어 올 수 있다.

SimpleXMLElement에서 필요한 정보를 얻어오는 가장 쉬운 방법은 해당 노드를 속성으로 지정하여 얻어오는 것이다.

$변수 = $개체->노드;

이런 식으로 작성한다. 여기서 "노드"라고 하는 것은, XML 데이터에 쓰여져 있는 하나 하나의 태그로 생각하면 된다. 이는 SimpleXMLElement 오브젝트로 생성되며, 각 태그마다 개체로 되어 있다. 이 개별 요소를 나타내는 개체를 노드라고 부르기도 한다.

XML에서는 동일한 이름의 노드가 같은 계층에 여러개 일 수도 있기에, 이러한 경우에는 그 노드를 나타내는 객체를 배열로 얻어온다. 따라서 지정된 노드를 얻어서 그것을 반복 등의 순서로 처리해 나가면, 여러 노드를 처리할 수 있다.

실제로 사용 예는 만들어 보겠다.

<?php
$data = "";
$xml = new SimpleXMLElement("data.xml",0,true);
$data_arr = $xml->data;
foreach ($data_arr as $row) {
    $data .= "<tr>";
    $data .= "<td>" . $row->name . "</td>";
    $data .= "<td>" . $row->version . "</td>";
    $data .= "<td>" . $row->price . "</td>";
    $data .= "</tr>";
}
?>
<!DOCTYPE html>
<html lang="ko">
    <head> 
        <meta http-equiv="Content-Type"
            content="text/html; charset=UTF-8" /> 
        <title>sample page</title>
        <style>
        h1 { font-size:14pt;
            padding:5px;
            background-color:#AAFFFF; }
        table tr td {
            padding:5px;
            background-color:#DDFFCC; }
        </style>
    </head>
    <body>
        <h1>Hello PHP!</h1>
        <table>
        <tr><th>Name</th><th>Version</th><th>Price</th></tr>
        <?php echo $data; ?>
        </table>
    </body>
</html>

여기에서는 방금 전의 data.xml을 로드하고 표시한다. 이 data.xml 파일에서 <datas>라는 태그가 루트에 있고, 그 안에 <data>라는 태그에 데이터가 저장되어 있다. 이 데이터는 제품 이름과 버전, 그리고 가격 등의 값이 저장되어 있다.

이 파일을 여기에서는 다음과 방식으로 읽어 오고 있다.

$xml = new SimpleXMLElement( "data.xml", 0, true);

data.xml으로 SimpleXMLElement의 객체 변수 $xml를 만들고, 그것로부터 <data> 태그 노드를 한꺼번에 가져온다.

$ data_arr = $xml->data;

위와 같이 $xml->data으로 노드 이름을 지정하여 노드를 꺼내온다. 정말 간단한다. 이 후에는 반복으로 하나 하나의 노드를 처리하고 있다.

foreach ($data_arr as $row) {...... 중략

이렇게 하면 노드 객체의 배열에서 순서대로 개체를 $row에 꺼내오고, 이 $row에서 각 요소의 값을 꺼내 텍스트로 만들어 간다.

$data .= "<td>" . $row->name . "</td>";
$data .= "<td>" . $row->version . "</td>";
$data .= "<td>" . $row->price . "</td>";

기본적인 사용법을 알면 XML의 이용은 매우 간단하다는 것을 알 수 있을 것이다.



노드를 조작하기

단순히 XML 데이터를 꺼내 출력뿐만 아니라 XML 데이터를 여러가지 조작해야 하는 경우가 있을 것이다. 예를 들어, 새로운 노드를 추가하거나 이미있는 노드를 삭제하는 등의 조작이다. 이러한 노드의 편집 작업에 대해 알아보자.

노드의 값 조작

이는 매우 간단하다. 이미 노드를 지정하는 방법은 알고 있을 것이고, 그 지정된 노드에 새 값을 할당하면 된다. 예를 들어, 이전에 XML 데이터에서 첫 번째 <data>의 <name> 값을 변경하고 싶다면, 아래와 같이 하면 된다.

$xml->data[0]->name = "값";

이렇게 하면 첫번째 (즉, 0번째) <data>의 <name> 값을 새로 변경이 된다. 만약, name이라고 노드가 없다면 새로 추가된다. (다음에 addChild라는 메소드를 설명하겠지만, 실은 이런 식으로 노드의 이름을 지정하고 값을 설정하면 addChild를 사용하지 않고도 노드를 추가할 수 있다.)

노드 추가

노드의 추가는 추가할 노드에서 "addChild"라는 메소드를 호출한다. 이는 다음과 같다.

노드->addChild(이름, 값);

첫번째 인수에 노드의 이름을, 두번째 인수에 설정되는 값을 각각 지정한다. 또한 세번째 인수에 네임스페이스를 지정하여 "OO라는 곳에 노드를 추가"와 같이 추가할 위치를 지정할 수도 있다. 아무튼, 우선은 첫번째, 두번째 인수만 알면 노드의 추가는 쉽게 할 수 있게 될 것이다.

예를 들어, 앞의 XML 데이터에서 첫 번째 <data>에 <maker>라는 노드를 추가하고 싶다면 다음과 같이 하면 된다.

$xml->data[0]->addChild('maker', 'microsoft');

노드 삭제

사실 삭제는 전용 메소드가 없고, 해당 노드의 속성을 unset 해 버리면 된다. 예를 들어, 앞의 XML 데이터에서 첫 번째 <data>를 삭제하고 싶다면 아래와 같이 하면 된다.

unset ($xml->data[o]);

속성(attribute) 조작

노드에는 값 외에 속성이라는 것도 있다. 예를 들어, 값은 <data>hoge</ data>라는 태그가 있을 경우 "hoge"가 값이 된다. 이와는 별도로 <data name="a">hoge</ data>와 같이 <data> 태그 내에 속성을 XML에서는 지정할 수 있다.

이 속성은 "addAttribute"라는 메소드로 쉽게 추가할 수 있다.

노드->addAttribute(이름, 값);

이런 식으로 하면 된다. 매우 간단하지만, 그 다른 값에 대한 갱신 또는 삭제에 대한 전용 메소드는 포함되어 있지 않다. "attributes"라는 메소드에서 노드에 포함되어 있는 모든 속성을 SimpleXMLElement으로 추출할 수 있지만, 이미 있는 속성을 삭제하는 등의 기능은 SimpleXML에는 없다.

 

그럼 노드와 속성을 조작하는 예제를 보도록 하자.

<?php
$arr = array('one', 'two', 'three');
$xml = new SimpleXMLElement("data.xml", 0, true);
for($i = 0; $i < count($arr); $i++) {
    $xml->data[$i]->version = $arr[$i];
    unset($xml->data[$i]->price);
    $newdata = $xml->addChild("otherdata", "");
    $newdata->addAttribute("number", $i + 1);
    $newdata->addChild("name", $arr[$i]);
}
header('content-type:text/xml;charset=utf-8');
echo $xml->asXML();

이전의 data.xml 파일을 로드하고, 그 내용을 편집하여 새로운 노드를 추가하고 XML 데이터로 출력한다. 여기서 <data>에서 <version>값을 변경하고, <price>를 제거한다. 또한 새롭게 <otherdata>라는 노드를 만들어서 number 속성과 name 노드를 추가한다.

수정된 SimpleXMLElement는 "asXML"라는 메소드를 사용해 XML 소스 코드로 출력한다. 이 asXML 메소드에 인수 등을 붙이지 않고 호출하게 되면, XML 소스 코드를 텍스트 값으로 반환한다. 수정한 XML 내용을 그대로 표시하는데 편리한다.

반응형

+ Recent posts