PHP操作XML详解

来源:互联网 发布:武媚娘传奇未剪胸 知乎 编辑:程序博客网 时间:2024/05/18 01:08

     XML是一种流行的半结构化文件格式,以一种类似数据库的格式存储数据。在实际应用中,一些简单的、安全性较低的数据往往使用 XML文件的格式进行存储。这样做的好处一方面可以通过减少与数据库的交互性操作提高读取效率,另一方面可以有效利用 XML的优越性降低程序的编写难度。
    PHP提供了一整套的读取 XML文件的方法,很容易的就可以编写基于 XML的脚本程序。本章将要介绍 PHP与 XML的操作方法,并对几个常用的 XML类库做一些简要介绍。

1 XML简介
XML是“可扩展性标识语言(eXtensible Markup Language)”的缩写,是一种类似于 HTML的标记性语言。但是与 HTML不同,XML主要用于描述数据和存放数据,而 HTML主要用于显示数据。
XML是一种“元标记”语言,开发者可以根据自己的需要创建标记的名称;在一个 XML文件的顶部,通常使用<?xml version="1.0" encoding="ISO-8859-1"?>来标识 XML数据的开始和 XML数据使用标准的版本信息.在浏览器中可直接访问 XML文件,能看到层次分明的 XML数据信息.

XML 还允许在起始标记中使用属性,提供元素的其他信息,如<contact id="1">,设置了属性id

2 简单的 XML操作
在实际应用中,PHP与 XML的交互操作应用非常广泛。SimpleXML组件是 PHP5新增加的一个简单的 XML操作组件,与传统的 XML组件相比,SimpleXML组件的使用非常简单。下面将通过例子对使用SimpleXML组件操作 XML的方法做一下详细介绍。

2.1 创建一个 SimpleXML对象
SimpleXML对象是用来临时存储 XML数据的临时变量,对 XML进行的操作都是通过操作 SimpleXML对象来完成的。SimpleXML组件提供了两种创建 SimpleXML对象的方法。第一种方法是使用 simplexml_load_string函数读取一个字符串型变量中的 XML数据来完成创建的,其语法格式如下所示,这里的 data变量用于存储 XML数据。
simplexml_load_string(string data)

<?php
$xmlstring = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<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($xmlstring);
print_r($xml);
?>

在上面的例子中,$data变量存储了一段 XML数据。 simplexml_load_string函数将变量$data转化成 SimpleXML对象。通过print_r()函数的输出可以看出该对象的结构;

第二种方法是使用 simplexml_load_flie函数读取一个 XML文件来完成创建的,其语法格式如下所示。
simplexml_load_file(string filename)
这里的 filename变量是用于存储 XML数据文件的文件名及其所在路径。

php代码:

<?php
$xml = simplexml_load_file("example.xml"); //创建 SimpleXML对象
print_r($xml);         //输出 XML
?>

example.xml的代码:同上面方法中的$data 中的报文体

<?xml version="1.0" encoding="ISO-8859-1"?>
      <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>

 

2.2 读取 SimpleXML对象中的 XML数据
前面介绍了使用 print_r函数来读取 SimpleXML对象中的数据,其返回结果与数组的结构类似。显然,这种显示方式在实际应用中是不可取的。在这里将介绍其他的几种读取 SimpleXML对象中 XML数据的方法。

1.var_dump函数显示对象详细信息:

var_dump函数可以用于显示 SimpleXML对象的详细信息,与 print_r函数相比,var_dump函数显示的信息更为完整,var_dump函数可打印多个变量。其语法如下所示。
void var_dump(object1, object2 … )
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>";
}
?>

具体过程是://读取 XML文件 //循环读取 XML数据中的每一个 depart标签 //输出其中的 name属性

也可以使用方括号“ []”来直接读取 XML数据中指定的标签。以下代码输出了上面 XML数据中的第一个“depart”标签的“name”属性。
<?php
$xml = simplexml_load_file("example.xml"); //读取 XML文件
echo $xml->depart->name[0]; //输出节点
?>

但是上段代码中,$xml->depart->name[1]; 打印出来是空。 why ?

对于一个标签下的所有子标签,SimpleXML组件提供了 children方法进行读取。例如,对于上面的 XML数据中的“ depart”标签,其下包括两个子标签:“ name”和“employees”。以下代码实现了对第一个“depart”标签下的子标签的读取。可以看出,使用 children方法后,所有的子标签均被当作一个新的 XML文件进行处理。

<?php
$xml = simplexml_load_file("example.xml");
foreach ($xml->depart->children() as $depart) //循环读取 depart标签下的子标签
{
var_dump($depart); //输出标签的 XML数据
}
?>

$xml->depart->children() 取子标签需要逐级取。如语句:$xml->depart->employees->employee->children() as $depar

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); //输出节点
?>

可发现:所有的 name标签均被查询出来了。

2.3 XML数据的修改
对于 XML数据的修改与读取 XML数据中的标签方法类似。即通过直接修改 SimpleXML对象中的标签的值来实现。以下代码实现了对上面 XML数据中第一个“ depart”标签的“ name”子标签的修改。修改后,并不会对 XML文件有任何影响。但是,在程序中,对于 SimpleXML对象的读取将使用修改过的值。

<?php
$xml = simplexml_load_file("example.xml"); //读取 XML
$xml->depart->name[0] = "Hunan Wander"; //修改节点
print_r($xml->depart->name[0]);
?>


2.4 标准化 XML数据
SimpleXML还提供了一种标准化 XML数据的方法 asXML。asXML方法可以有效的将 SimpleXML对象中的内容按照 XML 1.0标准进行重新编排并以字符串的数据类型返回。以下代码实现了对上面 XML数据的标准化。标准化之后的代码将以标准的xml格式输出,效果同在浏览器中直接输如example.xml:

<?php
$xml = simplexml_load_file("example.xml"); //读取 XML数据
echo $xml->asXML(); //标准化 XML数据
?>

2.5 XML数据的存储
将 SimpleXML对象中的 XML数据存储到一个 XML文件的方法非常简单,即将 asXML方法的返回结果输出到一个文件中即可,然后将修改过的 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); //关闭文件
?>

3 XML文档的动态创建
在实际应用中,时而会需要动态生成 XML文档的操作。前面介绍的 SimpleXML组件并不提供创建 XML文档的方法。因此,如果需要动态创建 XML文档,往往使用 DOM组件进行创建。 DOM是文档对象模型 Document Object Model的缩写, DOM组件提供了对 XML文档的树型解析模式。以下代码使用 DOM组件创建了一个 XML文档。DOM的更多内容页参考http://baike.baidu.com/view/1332772.htm

<?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();

?>

DOM组件除了可以用来动态创建 XML文档外,还可以用来读取 XML文件。以下代码实现了对前面 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);
}
}
}
?>

4 XML应用实例——留言本
前面介绍了 XML的基本操作,本节将以设计一个 XML留言本为例来详细说明在实际应用中如何实现 PHP与 XML数据的交互操作。
4.1 XML文件结构设计
XML文件用于存储 XML数据,也就是留言本中的留言。这里,对于每条留言,在 XML数据中主要包括三项内容:留言标题、留言者姓名、留言内容。因此,将 XML文件的格式设计如下。
newxml.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<threads>
</threads>

提交页面的编写:xmlparselearn.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="xmlparselearn.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页面代码:xmlparselearn.php(与文件newxml.xml放在同一目录下)

<?php
$guestbook = new DomDocument(); //创建一个新的 DOM对象
$guestbook->load("newxml.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("newxml.xml", "w");
if(fwrite($fp, $guestbook->saveXML()))
echo "留言提交成功";
else
echo "留言提交失败";
fclose($fp);
?>

执行成功之后,newxml.XML文件中已经将信息以报文的形式存储起来了。

4.3 显示页面的编写
显示页面可以使用前面介绍的 SimpleXML组件很容易的实现,具体实现代码如下所示。

<?php
//打开用于存储留言的 XML文件
$guestbook = simplexml_load_file("newxml.xml");
foreach($guestbook->thread as $th) //循环读取 XML数据中的每一个 thread标签
{
  echo "<B>标题:</B>".$th->title."<BR>";
  echo "<B>作者:</B>".$th->author."<BR>";
  echo "<B>内容:</B>".$th->content."<BR>";
  echo "<HR>";
}
?>