PHP解析XML文件

一、什么是 XML?
XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。

二、如何解析XML?
有两种基本的 XML 解析器类型:
基于树的解析器:这种解析器把 XML 文档转换为树型结构。它分析整篇文档,并提供了 API 来访问树种的元素,例如文档对象模型 (DOM)。
基于事件的解析器:将 XML 文档视为一系列的事件。当某个具体的事件发生时,解析器会调用函数来处理。如(PHP Expat)。

三、使用Expat解析器:
将在我们的例子中使用下面的 XML 文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
我们要在 PHP 中初始化 XML 解析器,为不同的 XML 事件定义处理器,然后解析这个 XML 文件。
<?php

//初始化XML解析器
$parser=xml_parser_create();

//开始标签函数
function start($parser,$element_name,$element_attrs)
 {
 switch($element_name)
{
case "NOTE":
echo "-- Note --<br />";
break; 
case "TO":
echo "To: ";
break; 
case "FROM":
echo "From: ";
break; 
case "HEADING":
echo "Heading: ";
break; 
case "BODY":
echo "Message: ";
}
 }

//结束标签函数
function stop($parser,$element_name)
 {
 echo "<br />";
 }

//数据函数
function char($parser,$data)
 {
 echo $data;
 }

//定义,当解析器遇到开始和结束标签时执行哪个函数
xml_set_element_handler($parser,"start","stop");

//函数来定义,当解析器遇到字符数据时执行哪个函数
xml_set_character_data_handler($parser,"char");

//打开XML文件
$fp=fopen("test.xml","r");

//读取数据
while ($data=fread($fp,4096))
 {
 xml_parse($parser,$data,feof($fp)) or 
 die (sprintf("XML Error: %s at line %d", 
 xml_error_string(xml_get_error_code($parser)),
 xml_get_current_line_number($parser)));
 }

//释放解析器所占资源
xml_parser_free($parser);

?>

以上代码的输出:
-- Note --
To: George
From: John
Heading: Reminder
Message: Don't forget the meeting!

工作原理解释:
通过 xml_parser_create() 函数初始化 XML 解析器
创建配合不同事件处理程序的的函数
添加 xml_set_element_handler() 函数来定义,当解析器遇到开始和结束标签时执行哪个函数
添加 xml_set_character_data_handler() 函数来定义,当解析器遇到字符数据时执行哪个函数
通过 xml_parse() 函数来解析文件 "test.xml"
万一有错误的话,添加 xml_error_string() 函数把 XML 错误转换为文本说明
调用 xml_parser_free() 函数来释放分配给 xml_parser_create() 函数的内存

四、使用DOM解析器:
XML文件仍然使用上例中的文件,循环 XML
我们要初始化 XML 解析器,加载 XML,并循环 <note> 元素的所有元素:
例子:
<?php
$xmlDoc = new DOMDocument();
$xmlDoc->load("note.xml");

$x = $xmlDoc->documentElement;
foreach ($x->childNodes AS $item)
 {
 print $item->nodeName . " = " . $item->nodeValue . "<br />";
 }
?>

以上代码的输出:
#text = 
to = George
#text = 
from = John
#text = 
heading = Reminder
#text = 
body = Don't forget the meeting!
#text = 

在上面的例子中,您看到了每个元素之间存在空的文本节点。当 XML 生成时,它通常会在节点之间包含空白。XML DOM解析器把它们当作普通的元素,如果您不注意它们,有时会产生问题。

DOMDocument的属性:    
Attributes     存储节点的属性列表(只读)   
childNodes     存储节点的子节点列表(只读)   
dataType     返回此节点的数据类型   
Definition     以DTD或XML模式给出的节点的定义(只读)   
Doctype     指定文档类型节点(只读)   
documentElement     返回文档的根元素(可读写)   
firstChild     返回当前节点的第一个子节点(只读)   
Implementation     返回XMLDOMImplementation对象   
lastChild     返回当前节点最后一个子节点(只读)   
nextSibling     返回当前节点的下一个兄弟节点(只读)   
nodeName     返回节点的名字(只读)   
nodeType     返回节点的类型(只读)   
nodeTypedValue   存储节点值(可读写)   
nodeValue     返回节点的文本(可读写)   
ownerDocument     返回包含此节点的根文档(只读)   
parentNode     返回父节点(只读)   
Parsed     返回此节点及其子节点是否已经被解析(只读)   
Prefix     返回名称空间前缀(只读)   
preserveWhiteSpace   指定是否保留空白(可读写)   
previousSibling     返回此节点的前一个兄弟节点(只读)   
Text     返回此节点及其后代的文本内容(可读写)   
url     返回最近载入的XML文档的URL(只读)   
Xml     返回节点及其后代的XML表示(只读)

DOMDocument的方法: 
appendChild     为当前节点添加一个新的子节点,放在最后的子节点后   
cloneNode     返回当前节点的拷贝   
createAttribute     创建新的属性   
createCDATASection     创建包括给定数据的CDATA段   
createComment     创建一个注释节点   
createDocumentFragment     创建DocumentFragment对象   
createElement     创建一个元素节点   
createEntityReference     创建EntityReference对象   
createNode       创建给定类型,名字和命名空间的节点   
createPorcessingInstruction     创建操作指令节点   
createTextNode     创建包括给定数据的文本节点   
getElementsByTagName     返回指定名字的元素集合   
hasChildNodes     返回当前节点是否有子节点   
insertBefore     在指定节点前插入子节点   
load     导入指定位置的XML文档   
loadXML     导入指定字符串的XML文档   
removeChild     从子结点列表中删除指定的子节点   
replaceChild     从子节点列表中替换指定的子节点   
Save     把XML文件存到指定节点   
selectNodes     对节点进行指定的匹配,并返回匹配节点列表   
selectSingleNode     对节点进行指定的匹配,并返回第一个匹配节点   
transformNode     使用指定的样式表对节点及其后代进行转换

五、PHP SimpleXML解析XML:
SimpleXML 是 PHP 5 中的新特性。在了解 XML 文档 layout 的情况下,它是一种取得元素属性和文本的便利途径。
与 DOM 或 Expat 解析器相比,SimpleXML 仅仅用几行代码就可以从元素中读取文本数据。

SimpleXML 可把 XML 文档转换为对象,比如:
元素 - 被转换为 SimpleXMLElement 对象的单一属性。当同一级别上存在多个元素时,它们会被置于数组中。
属性 - 通过使用关联数组进行访问,其中的下标对应属性名称。
元素数据 - 来自元素的文本数据被转换为字符串。如果一个元素拥有多个文本节点,则按照它们被找到的顺序进行排列。

当执行类似下列的基础任务时,SimpleXML 使用起来非常快捷:
读取 XML 文件
从 XML 字符串中提取数据
编辑文本节点或属性

不过,在处理高级 XML 时,比如命名空间,最好使用 Expat 解析器或 XML DOM。

同样使用最开始的XML,例子如下:
<?php
$xml = simplexml_load_file("test.xml");

echo $xml->getName() . "<br />";

foreach($xml->children() as $child)
 {
 echo $child->getName() . ": " . $child . "<br />";
 }
?>

以上代码的输出:
note
to: George
from: John
heading: Reminder
body: Don't forget the meeting!

如下代码:
<?php
$xml = simplexml_load_file("test.xml");
echo $xml->getName()."<br/>";
echo $xml->to->getName() . ": " . $xml->to . "<br />";
echo $xml->from->getName() . ": " . $xml->from . "<br />";
echo $xml->heading->getName() . ": " . $xml->heading . "<br />";
echo $xml->body->getName() . ": " . $xml->body . "<br />";
?>

同样可得上述结果(即当我们知道XML文件的结构时,我们可以用这种方法获取我们需要的结点值)。

六、SimpleXML常用的几个函数:

A.simplexml_load_file()
用于加载XML文件,如上例中的使用。

B.simplexml_load_string()
用于加载字符串的XML,常用于加载在PHP文件中生成的XML。
例:
<?php
$str = "<?xml version='1.0' encoding='ISO-8859-1'?><note><to>George</to><from>John</from><heading>Reminder</heading>"
."<body>Don't forget the meeting!</body></note>";
$xml=simplexml_load_string($str);
print_r($xml);
?>
输出结果:
SimpleXMLElement Object ( [to] => George [from] => John [heading] => Reminder [body] => Don't forget the meeting! )

C.xpath()
用于设置访问路径,将结果放入一个数组返回。如:
<?php
$xml=simplexml_load_file("test.xml");
$res = $xml->xpath("to");
print_r($res);
?>
输出结果:
Array ( [0] => SimpleXMLElement Object ( [0] => George ) )

D.asXML()
用于格式化XML,返回一个XML1.0标准的XML。

七、后记:
本文简单介绍了PHP解析XML的三种方法,主要参考了w3school中的相关内容,并借用了其中的一些实例。主要目的是为了方便自己以后的查阅,也希望对他人有所帮助。

版权声明:本文为newlife007原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。