XML은 데이터베이스와 같은 형식으로 데이터를 저장하는 인기 있는 반구조적 파일 형식입니다. 실제 응용 프로그램에서는 단순하고 보안 수준이 낮은 일부 데이터가 XML 파일 형식으로 저장되는 경우가 많습니다. 이것의 장점은 한편으로는 데이터베이스와의 상호 작용을 줄여 읽기 효율성을 높일 수 있고, 다른 한편으로는 XML의 장점을 효과적으로 활용하여 프로그램 작성의 어려움을 줄일 수 있다는 것입니다.
PHP는 XML 파일을 읽는 완전한 방법 세트를 제공하므로 XML 기반 스크립트를 쉽게 작성할 수 있습니다. 이 장에서는 PHP와 XML의 작업 방법을 소개하고 일반적으로 사용되는 여러 XML 클래스 라이브러리에 대해 간략하게 소개합니다.
1 XML 소개
XML은 "eXtensible Markup Language"의 약자로 HTML과 유사한 마크업 언어입니다. 그러나 HTML과 달리 XML은 주로 데이터를 설명하고 데이터를 저장하는 데 사용되는 반면 HTML은 주로 데이터를 표시하는 데 사용됩니다.
XML은 개발자가 필요에 따라 태그 이름을 만들 수 있는 "메타 태그" 언어입니다. 예를 들어 다음 XML 코드를 사용하여 메시지를 설명할 수 있습니다.
<thread> <title>Welcome</title> <author>Simon</author> <content>Welcome to XML guestbook!!</content> </thread>
그 중 61fe42cd48946e53c78c0e2bbfbc7b04 및 2dae87978011c3a138ff06fa01f47109 태그는 이를 메시지로 표시합니다. 메시지에는 제목, 작성자, 내용이 있어 메시지 메시지를 완벽하게 표현합니다.
XML 파일의 상단에는 일반적으로 XML 데이터의 시작 부분을 식별하기 위해 cf5d35bd4deb7fb38b28e6dfcfe14665을 사용하며 XML 데이터는 표준 버전 정보를 사용합니다. 브라우저에서 XML 파일에 액세스하면 그림 1과 같이 명확하게 구조화된 XML 데이터 정보를 볼 수 있습니다.
최근 몇 년 동안 많은 소프트웨어 개발자가 애플리케이션 개발에 XML 개발 표준을 채택하기 시작했습니다. 더욱이 많은 최신 기술은 XML 데이터를 기반으로 구축되었습니다. 이는 XML이 HTML만큼 웹 기술의 필수적인 부분이 될 것임을 의미합니다.
2 간단한 XML 작업
실제 응용 프로그램에서는 PHP와 XML의 대화형 작업이 널리 사용됩니다. SimpleXML 구성 요소는 PHP5에 새로 추가된 단순 XML 작업 구성 요소로, 기존 XML 구성 요소와 비교하여 SimpleXML 구성 요소의 사용이 매우 간단합니다. 이번 섹션에서는
SimpleXML 컴포넌트를 사용하여 XML을 조작하는 방법을 자세히 소개합니다.
2.1 SimpleXML 개체 만들기
SimpleXML 개체는 XML 데이터를 임시로 저장하는 데 사용되는 임시 변수입니다. XML에 대한 작업은 SimpleXML 개체를 작업하여 완료됩니다. SimpleXML 구성 요소는 SimpleXML 개체를 만드는 두 가지 방법을 제공합니다. 첫 번째 방법은 simplexml_load_string 함수를 사용하여 문자열 변수의 XML 데이터를 읽어서 생성을 완료하는 것입니다.
simplexml_load_string(string data)
여기서 data 변수는 XML 데이터를 저장하는 데 사용됩니다. 다음 코드는 simplexml_load_string 함수를 사용하여 SimpleXML 객체를 생성합니다.
<?php $data = <<<XML //定义 XML数据 <?xml version='1.0′?> <departs> <depart> <name>production support</name> <employees> <employee> <serial_no>100001</serial_no> <name>Simon</name> <age>24</age> <birthday>1982-11-06</birthday> <salary>5000.00</salary> <bonus>1000.00</bonus> </employee> <employee> <serial_no>100002</serial_no> <name>Elaine</name> <age>24</age> <birthday>1982-01-01</birthday> <salary>6000.00</salary> <bonus>2000.00</bonus> </employee> </employees> </depart> <depart> <name>testing center</name> <employees> <employee> <serial_no>110001</serial_no> <name>Helen</name> <age>23</age> <birthday>1983-07-21</birthday> <salary>5000.00</salary> <bonus>1000.00</bonus> </employee> </employees> </depart> </departs> XML; $xml = simplexml_load_string($data); //创建 SimpleXML对象 print_r($xml); //输出 XML ?>위 예에서 $data 변수는 XML 데이터를 저장합니다. simplexml_load_string 함수는 $data 변수를 SimpleXML 개체로 변환합니다. 객체의 구조는 print_r 함수의 출력을 통해 확인할 수 있으며, 실행 결과는 다음과 같다.
SimpleXMLElement Object ( [depart] => Array ( [0] => SimpleXMLElement Object ( [name] => production support [employees] => SimpleXMLElement Object ( [employee] => Array ( [0] => SimpleXMLElement Object ( [serial_no] => 100001 [name] => Simon [age] => 24 [birthday] => 1982-11-06 [salary] => 5000.00 [bonus] => 1000.00 ) [1] => SimpleXMLElement Object ( [serial_no] => 100002 [name] => Elaine [age] => 24 [birthday] => 1982-01-01 [salary] => 6000.00 [bonus] => 2000.00 ) ) ) ) [1] => SimpleXMLElement Object ( [name] => testing center [employees] => SimpleXMLElement Object ( [employee] => SimpleXMLElement Object ( [serial_no] => 110001 [name] => Helen [age] => 23 [birthday] => 1983-07-21 [salary] => 5000.00 [bonus] => 1000.00 ) ) ) ) )출력 결과에서 볼 수 있듯이 SimpleXML 객체의 구조는 XML 데이터의 형식과 완전히 동일합니다.
두 번째 방법은 simplexml_load_flie 함수를 사용하여 XML 파일을 읽어서 생성을 완료하는 것입니다.
simplexml_load_file(string filename)
여기서 filename 변수는 XML 데이터 파일을 저장하는 데 사용되는 파일 이름과 경로입니다. 다음 코드는 simplexml_load_file 함수를 사용하여 SimpleXML 객체를 생성합니다.
<?php $xml = simplexml_load_file('example.xml'); //创建 SimpleXML对象 print_r($xml); //输出 XML ?>그 중 example.xml에 저장된 데이터는 위의 $data와 똑같고, 실행 결과도 위와 똑같습니다.
위의 두 가지 방법은 동일한 기능을 구현하지만 차이점은 XML의 데이터 소스가 다르다는 것입니다. XML 데이터 소스가 PHP 스크립트 파일에 있는 경우 simplexml_load_string을 사용하여 이를 생성해야 합니다. XML 데이터 소스가 별도의 XML 파일에 있는 경우 simplexml_load_file을 사용하여 생성해야 합니다.
2.2 SimpleXML 객체에서 XML 데이터 읽기
이전에는 SimpleXML 객체에서 데이터를 읽기 위해 print_r 함수를 사용하는 방법을 소개했는데, 반환 결과는 배열의 구조와 유사합니다. 분명히, 이 표시 방법은 실제 응용에서는 바람직하지 않습니다. 여기에서는 SimpleXML 객체에서 XML 데이터를 읽는 몇 가지 다른 방법을 소개합니다.
1. var_dump 함수는 객체 세부 정보를 표시합니다
var_dump 함수는 SimpleXML 객체의 세부 정보를 표시하는 데 사용할 수 있습니다. print_r 함수와 비교하여 var_dump 함수의 구문은 다음과 같습니다.
void var_dump(object1, object2 … )
다음 코드는 var_dump 함수를 사용하여 위 예제의 객체에 대한 자세한 정보를 출력합니다.
<?php $xml = simplexml_load_file('example.xml'); //创建 SimpleXML对象 var_dump($xml); //输出 XML ?>실행 결과는 다음과 같습니다.
object(SimpleXMLElement)#1 (1) { ["depart"]=> array(2) { [0]=> object(SimpleXMLElement)#2 (2) { ["name"]=> string(18) “production support” ["employees"]=> object(SimpleXMLElement)#4 (1) { ["employee"]=> array(2) { [0]=> object(SimpleXMLElement)#5 (6) { ["serial_no"]=> string(6) “100001″ ["name"]=> string(5) “Simon” ["age"]=> string(2) “24″ ["birthday"]=> string(10) “1982-11-06″ ["salary"]=> string(7) “5000.00″ ["bonus"]=> string(7) “1000.00″ } [1]=> object(SimpleXMLElement)#6 (6) { ["serial_no"]=> string(6) “100002″ ["name"]=> string(6) “Elaine” ["age"]=> string(2) “24″ ["birthday"]=> string(10) “1982-01-01″ ["salary"]=> string(7) “6000.00″ ["bonus"]=> string(7) “2000.00″ } } } } [1]=> object(SimpleXMLElement)#3 (2) { ["name"]=> string(14) “testing center” ["employees"]=> object(SimpleXMLElement)#7 (1) { ["employee"]=> object(SimpleXMLElement)#8 (6) { ["serial_no"]=> string(6) “110001″ ["name"]=> string(5) “Helen” ["age"]=> string(2) “23″ ["birthday"]=> string(10) “1983-07-21″ ["salary"]=> string(7) “5000.00″ ["bonus"]=> string(7) “1000.00″ }}}}}
与前面 print_r输出的结果相比较,var_dump函数的输出结果的结构更为严谨,并且将对象中的每一个属性的数据类型均作出分析。在实际应用中,var_dump函数往往用于程序调试时的对象检测。
2.读取 XML数据中的标签
与操作数组类型的变量类似,读取 XML也可以通过类似的方法来完成。例如,如果需要读取上面 XML数据中每一个“ depart”标签下的“name”属性,可以通过使用 foreach函数来完成,如以下代码
所示。
<?php $xml = simplexml_load_file('example.xml'); foreach($xml->depart as $a) { echo “$a->name <BR>”; } ?>
运行结果如下所示。
production support
testing center
//读取 XML文件 //循环读取 XML数据中的每一个 depart标签
//输出其中的 name属性
也可以使用方括号“ []”来直接读取 XML数据中指定的标签。以下代码输出了上面 XML数据中的第一个“depart”标签的“name”属性。
<?php $xml = simplexml_load_file('example.xml'); //读取 XML文件 echo $xml->depart->name[0]; //输出节点 ?>
运行结果如下所示。
production support
对于一个标签下的所有子标签,SimpleXML组件提供了 children方法进行读取。例如,对于上面的 XML数据中的“ depart”标签,其下包括两个子标签:“ name”和“employees”。以下代码实现了对第一个“depart”标签下的子标签的读取。
<?php $xml = simplexml_load_file('example.xml'); foreach ($xml->depart->children() as $depart) //循环读取 depart标签下的子标签 { var_dump($depart); //输出标签的 XML数据 } ?>
运行结果如下所示。
object(SimpleXMLElement)#3 (1) { [0]=> string(18) “production support” } object(SimpleXMLElement)#5 (1) { ["employee"]=> array(2) { [0]=> object(SimpleXMLElement)#3 (6) { ["serial_no"]=> string(6) “100001″ ["name"]=> string(5) “Simon” ["age"]=> string(2) “24″ ["birthday"]=> string(10) “1982-11-06″ ["salary"]=> string(7) “5000.00″ ["bonus"]=> string(7) “1000.00″ } [1]=> object(SimpleXMLElement)#6 (6) { ["serial_no"]=> string(6) “100002″ ["name"]=> string(6) “Elaine” ["age"]=> string(2) “24″ ["birthday"]=> string(10) “1982-01-01″ ["salary"]=> string(7) “6000.00″ ["bonus"]=> string(7) “2000.00″ } } }
可以看出,使用 children方法后,所有的子标签均被当作一个新的 XML文件进行处理。
3.基于 XML数据路径的查询
SimpleXML组件提供了一种基于 XML数据路径的查询方法。 XML数据路径即从 XML的根到某一个标签所经过的全部标签。这种路径使用斜线“ /”隔开标签名。例如,对于上面的 XML数据,要查询所有的标签“name”中的值,从根开始要经过 departs、depart、employees和 employee标签,则其路径
为“/departs/depart/employees/employee/name”。 SimpleXML组件使用 xpath方法来解析路径,其语法格式如下所示。
xpath(string path)
其中的 path为路径。该方法返回了一个包含有所有要查询标签值的数组。以下代码查询了上面 XML数据中的所有 name标签。
<?php $xml = simplexml_load_file('example.xml'); //读取 XML文件 $result = $xml->xpath('/departs/depart/employees/employee/name'); //定义节点 var_dump($result); //输出节点 ?>
运行结果如下所示。
array(3) { [0]=> object(SimpleXMLElement)#2 (1) { [0]=> string(5) “Simon” } [1]=> object(SimpleXMLElement)#3 (1) { [0]=> string(6) “Elaine” } [2]=> object(SimpleXMLElement)#4 (1) { [0]=> string(5) “Helen” } }
可以看出,所有的 name标签均被查询出来。
2.3 XML数据的修改
对于 XML数据的修改与读取 XML数据中的标签方法类似。即通过直接修改 SimpleXML对象中的标签的值来实现。以下代码实现了对上面 XML数据中第一个“ depart”标签的“ name”子标签的修改。
<?php $xml = simplexml_load_file('example.xml'); //读取 XML $xml->depart->name[0] = “Human Resource”; //修改节点 ?>
修改后,并不会对 XML文件有任何影响。但是,在程序中,对于 SimpleXML对象的读取将使用修改过的值。
2.4 标准化 XML数据
SimpleXML还提供了一种标准化 XML数据的方法 asXML。asXML方法可以有效的将 SimpleXML对象中的内容按照 XML 1.0标准进行重新编排并以字符串的数据类型返回。以下代码实现了对上面 XML数据的标准化。
<?php $xml = simplexml_load_file('example.xml'); //读取 XML数据 echo $xml->asXML(); //标准化 XML数据 ?>
2.5 XML数据的存储
将 SimpleXML对象中的 XML数据存储到一个 XML文件的方法非常简单,即将 asXML方法的返回结果输出到一个文件中即可。以下代码首先将 XML文件中的 depart name进行了修改,然后将修改过的 XML数据输出到另一个 XML文件。
<?php $xml = simplexml_load_file('example.xml'); //读取 XML数据 $newxml = $xml->asXML(); //标准化 XML数据 $fp = fopen(”newxml.xml”, “w”); //打开要写入 XML数据的文件 fwrite($fp, $newxml); //写入 XML数据 fclose($fp); //关闭文件 ?>
代码运行后,可以看到在 newxml.xml文件中的 XML数据如下所示。
可以看出,对于 XML文件的修改已经保存到输出文件中了。
3 XML文档的动态创建
在实际应用中,时而会需要动态生成 XML文档的操作。前面介绍的 SimpleXML组件并不提供创建 XML文档的方法。因此,如果需要动态创建 XML文档,往往使用 DOM组件进行创建。 DOM是文档对象模型 Document Object Model的缩写, DOM组件提供了对 XML文档的树型解析模式。以下代码使用 DOM组件创建了一个 XML文档。
<?php //创建一个新的 DOM文档 $dom = new DomDocument(); //在根节点创建 departs标签 $departs = $dom->createElement('departs'); $dom->appendChild($departs); //在 departs标签下创建 depart子标签 $depart = $dom->createElement('depart'); $departs->appendChild($depart); //在 depart标签下创建 employees子标签 $employees = $dom->createElement('employees'); $depart->appendChild($employees); //在 employees标签下创建 employee子标签 $employee = $dom->createElement('employee'); $employees->appendChild($employee); //在 employee标签下创建 serial_no子标签 $serial_no = $dom->createElement('serial_no'); $employee->appendChild($serial_no); //为 serial_no标签添加值节点 100001 $serial_no_value = $dom->createTextNode('100001′); $serial_no->appendChild($serial_no_value); //输出 XML数据 echo $dom->saveXML(); ?> 输出结果如下所示。 <?xml version=”1.0″?> <departs> <depart> <employees> <employee> <serial_no>100001</serial_no> </employee> </employees> </depart> </departs>
DOM组件除了可以用来动态创建 XML文档外,还可以用来读取 XML文件。以下代码实现了对前 面 XML文件的读取。
<?php $dom = new DomDocument(); //创建 DOM对象 $dom->load('example.xml'); //读取 XML文件 $root = $dom->documentElement; //获取 XML数据的根 read_child($root); //调用 read_child函数读取根对象 function read_child($node) { $children = $node->childNodes; //获得$node的所有子节点 foreach($children as $e) //循环读取每一个子节点 { if($e->nodeType == XML_TEXT_NODE) //如果子节点为文本型则输出 { echo $e->nodeValue.”<BR>”; } else if($e->nodeType == XML_ELEMENT_NODE) //如果子节点为节点对象,则调用函数处理 { read_child($e); } } } ?>
运行结果如下所示。
引用 production support 100001 Simon 24 1982-11-06 5000.00 1000.00 100002 Elaine 24 1982-01-01 6000.00 2000.00 testing center 110001 Helen 23 1983-07-21 5000.00 1000.00
上面的例子使用了递归的方式对 XML数据进行了处理,实现了输出 XML数据中的所有文本型标签的功能。
4 XML应用实例——留言本
前面介绍了 XML的基本操作,本节将以设计一个 XML留言本为例来详细说明在实际应用中如何实现 PHP与 XML数据的交互操作。
4.1 XML文件结构设计
XML文件用于存储 XML数据,也就是留言本中的留言。这里,对于每条留言,在 XML数据中主要包括三项内容:留言标题、留言者姓名、留言内容。因此,将 XML文件的格式设计如下。
<?xml version=”1.0″?> <threads> <thread> <title>这里是留言的标题</title> <author>这里是留言者</author> <content>这里是留言内容</content> </thread> </threads>
4.2 提交页面的编写
提交留言页面由两个页面组成。一个是让访问者用来书写留言的表单的 HTML文件,一个是用来处理访问者输入的 PHP脚本。表单的 HTML代码如下所示。
<html> <head> <title>发表新的留言</title> <meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″> </head> <body> <H1><p align=”center”>发表新的留言</p></H1> <form name=”form1″ method=”post” action=”Post.php”> <table width=”500″ border=”0″ align=”center” cellpadding=”0″ cellspacing=”0″> <tr> <td>标题</td> <td><input name=”title” type=”text” id=”title” size=”50″></td> </tr> <tr> <td>作者</td> <td><input name=”author” type=”text” id=”author” size=”20″></td> </tr> <tr> <td>内容</td> <td><textarea name=”content” cols=”50″ rows=”10″ id=”content”></textarea></td> </tr> </table> <p align=”center”> <input type=”submit” value=”Submit”> <input type=”reset” value=”Reset”> </p> </form> </body> </html>
对于用来处理用户输入的 PHP脚本,其基本逻辑是首先创建一个 DOM对象,然后读取 XML文件中的 XML数据,接下来在 XML对象上创建新的节点并将用户的输入储存起来,最后将 XML数据输出到原来的 XML文件中。具体实现代码如下所示。
<?php $guestbook = new DomDocument(); //创建一个新的 DOM对象 $guestbook->load('DB/guestbook.xml'); //读取 XML数据 $threads = $guestbook->documentElement; //获得 XML结构的根 //创建一个新 thread节点 $thread = $guestbook->createElement('thread'); $threads->appendChild($thread); //在新的 thread节点上创建 title标签 $title = $guestbook->createElement('title'); $title->appendChild($guestbook->createTextNode($_POST['title'])); $thread->appendChild($title); //在新的 thread节点上创建 author标签 $author = $guestbook->createElement('author'); $author->appendChild($guestbook->createTextNode($_POST['author'])); $thread->appendChild($author); //在新的 thread节点上创建 content标签 $content = $guestbook->createElement('content'); $content->appendChild($guestbook->createTextNode($_POST['content'])); $thread->appendChild($content); //将 XML数据写入文件 $fp = fopen(”DB/guestbook.xml”, “w”); if(fwrite($fp, $guestbook->saveXML())) echo “留言提交成功”; else echo “留言提交失败”; fclose($fp); ?>
在浏览器中运行上述 HTML文件并填写适当的留言内容,如图 2所示。
图 2 发表新留言界面
单击【Submit】按钮后,XML文件中的内容如下所示。
可以看到 XML文件中已经将留言存储起来了。
4.3 显示页面的编写
显示页面可以使用前面介绍的 SimpleXML组件很容易的实现,具体实现代码如下所示。
<?php //打开用于存储留言的 XML文件 $guestbook = simplexml_load_file('DB/guestbook.xml'); foreach($guestbook->thread as $th) //循环读取 XML数据中的每一个 thread标签 { echo “<B>标题:</B>”.$th->title.”<BR>”; echo “<B>作者:</B>”.$th->author.”<BR>”; echo “<B>内容:</B><PRE>”.$th->content.””; echo “
在浏览器中查看运行结果如图 3所示。
更多PHP XML操作的各种方法解析(比较详细)相关文章请关注PHP中文网!