仓酷云

标题: PHP网页编程之用PHP读取和编写XML DOM的完成代码 [打印本页]

作者: 小妖女    时间: 2015-2-3 23:39
标题: PHP网页编程之用PHP读取和编写XML DOM的完成代码
你的留言本应该加入注册以及分页功能了,而如果你更强的话,UI(用户界面)也可以加强,完成之后,感觉是不是特有成就感?不管怎么样,咱好歹是写了一个动态网站程序了,放在自己的网站上耍耍吧。   用 PHP 读取和编写可扩大标志言语(XML)看起来能够有点可骇。实践上,XML 和它的一切相干手艺多是可骇的,然而用 PHP 读取和编写 XML 纷歧定是项可骇的义务。起首,需求进修一点关于 XML 的常识 ―― 它是甚么,用它做甚么。然后,需求进修若何用 PHP 读取和编写 XML,而有很多种体例可以做这件事。
本文供应了 XML 的冗长入门,然后注释若何用 PHP 读取和编写 XML。
甚么是 XML?
XML 是一种数据存储格局。它没有界说保留甚么数据,也没有界说数据的格局。XML 只是界说了标志和这些标志的属性。格局优秀的 XML 标志看起来像如许:
<name>Jack Herrington</name>
这个 <name> 标志包括一些文本:Jack Herrington。
不包括文本的 XML 标志看起来像如许:
<powerUp />
用 XML 对某件事停止编写的体例不止一种。例如,这个标志构成的输入与前一个标志不异:
<powerUp></powerUp>
也能够向 XML 标志添加属性。例如,这个 <name> 标志包括 first 和 last 属性:
<name first="Jack" last="Herrington" />
也能够用 XML 对特别字符停止编码。例如,& 符号可以像如许编码:
&
包括标志和属性的 XML 文件假如像示例一样格局化,就是格局优秀的,这意味着标志是对称的,字符的编码准确。清单 1 是一份格局优秀的 XML 的示例。

清单 1. XML 图书列暗示例
复制代码 代码以下:
<books>
<book>
<author>Jack Herrington</author>
<title>PHP Hacks</title>
<publisher>O"Reilly</publisher>
</book>
<book>
<author>Jack Herrington</author>
<title>Podcasting Hacks</title>
<publisher>O"Reilly</publisher>
</book>
</books>

清单 1 中的 XML 包括一个图书列表。父标志 <books> 包括一组 <book> 标志,每一个 <book> 标志又包括 <author>、<title> 和 <publisher> 标志。
当 XML 文档的标志布局和内容失掉内部形式文件的验证后,XML 文档就是准确的。形式文件可以用分歧的格局指定。关于本文来讲,所需求的只是格局优秀的 XML。
假如感觉 XML 看起来很像超文本标志言语(HTML),那末就对了。XML 和 HTML 都是基于标志的言语,它们有很多类似的地方。然而,要侧重指出的是:固然 XML 文档多是格局优秀的 HTML,但不是一切的 HTML 文档都是格局优秀的 XML。换行标志(br)是 XML 和 HTML 之间区分的一个好例子。这个换行标志是格局优秀的 HTML,但不是格局优秀的 XML:
<p>This is a paragraph<br>
With a line break</p>
这个换行标志是格局优秀的 XML 和 HTML:
<p>This is a paragraph<br />
With a line break</p>
假如要把 HTML 编写成一样是格局优秀的 XML,请遵守 W3C 委员会的可扩大超文本标志言语(XHTML)尺度。一切古代的阅读器都能出现 XHTML。并且,还可以用 XML 东西读取 XHTML 并找出文档中的数据,这比解析 HTML 轻易很多。
利用 DOM 库读取 XML
读取格局优秀的 XML 文件最轻易的体例是利用编译成某些 PHP 装置的文档对象模子 (DOM)库。DOM 库把全部 XML 文档读入内存,并用节点树暗示它,如图 1 所示。
图 1. 图书 XML 的 XML DOM 树
PHP网页编程之用PHP读取和编写XML DOM的完成代码
登录/注册后可看大图

树顶部的 books 节点有两个 book 子标志。在每本书中,有 author、publisher 和 title 几个节点。author、publisher 和 title 节点分离有包括文本的文簿子节点。
读取图书 XML 文件并用 DOM 显示内容的代码如清单 2 所示。
清单 2. 用 DOM 读取图书 XML
复制代码 代码以下:
<?php
$doc = new DOMDocument();
$doc->load( "books.xml" );
$books = $doc->getElementsByTagName( "book" );
foreach( $books as $book )
{
$authors = $book->getElementsByTagName( "author" );
$author = $authors->item(0)->nodeValue;
$publishers = $book->getElementsByTagName( "publisher" );
$publisher = $publishers->item(0)->nodeValue;
$titles = $book->getElementsByTagName( "title" );
$title = $titles->item(0)->nodeValue;
echo "$title - $author - $publisher\n";
}
?>

剧本起首创立一个 new DOMdocument 对象,用 load 办法把图书 XML 装入这个对象。以后,剧本用 getElementsByName 办法失掉指命名称下的一切元素的列表。
在 book 节点的轮回中,剧本用 getElementsByName 办法取得 author、publisher 和 title 标志的 nodeValue。nodeValue 是节点中的文本。剧本然后显示这些值。
可以在号令行上像如许运转 PHP 剧本:
% php e1.php
PHP Hacks - Jack Herrington - O"Reilly
Podcasting Hacks - Jack Herrington - O"Reilly
%
可以看到,每一个图书块输入一行。这是一个优秀的入手下手。然而,假如不克不及会见 XML DOM 库该怎样办?
用 SAX 解析器读取 XML
读取 XML 的另外一种办法是利用 XML Simple API(SAX)解析器。PHP 的大多半装置都包括 SAX 解析器。SAX 解析器运转在回调模子上。每次翻开或封闭一个标志时,或每次解析器看到文本时,就用节点或文本的信息回挪用户界说的函数。
SAX 解析器的长处是,它是真正轻量级的。解析器不会在内存中临时坚持内容,所以可以用于十分伟大的文件。弱点是编写 SAX 解析器回调是件十分费事的事。清单 3 显示了利用 SAX 读取图书 XML 文件并显示内容的代码。
清单 3. 用 SAX 解析器读取图书 XML
复制代码 代码以下:
<?php
$g_books = array();
$g_elem = null;
function startElement( $parser, $name, $attrs )
{
global $g_books, $g_elem;
if ( $name == "BOOK" ) $g_books []= array();
$g_elem = $name;
}
function endElement( $parser, $name )
{
global $g_elem;
$g_elem = null;
}
function textData( $parser, $text )
{
global $g_books, $g_elem;
if ( $g_elem == "AUTHOR"
$g_elem == "PUBLISHER"
$g_elem == "TITLE" )
{
$g_books[ count( $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 as $book )
{
echo $book["TITLE"]." - ".$book["AUTHOR"]." - ";
echo $book["PUBLISHER"]."\n";
}
?>

剧本起首设置 g_books 数组,它在内存中包容一切图书和图手札息,g_elem 变量保留剧本今朝正在处置的标志的称号。然后剧本界说回调函数。在这个示例中,回调函数是 startElement、endElement 和 textData。在翻开和封闭标志的时分,分离挪用 startElement 和 endElement 函数。在入手下手和停止标志之间的文本下面,挪用 textData。
在这个示例中,startElement 标志查找 book 标志,在 book 数组中入手下手一个新元素。然后,textData 函数检查以后元素,看它是否是 publisher、title 或 author 标志。假如是,函数就把以后文本放入以后图书。
为了让解析持续,剧本用 xml_parser_create 函数创立解析器。然后,设置回调句柄。以后,剧本读取文件并把文件的大块内容发送到解析器。在文件读取以后,xml_parser_free 函数删除解析器。剧本的末尾输入 g_books 数组的内容。
可以看到,这比编写 DOM 的一样功效要坚苦很多。假如没有 DOM 库也没有 SAX 库该怎样办?还有替换计划么?
--------------------------------------------------------------------------------
回页首
用正则表达式解析 XML
可以一定,即便提到这个办法,有些工程师也会品评我,然而的确可以用正则表达式解析 XML。清单 4 显示了利用 preg_ 函数读取图书文件的示例。
清单 4. 用正则表达式读取 XML
复制代码 代码以下:
<?php
$xml = "";
$f = fopen( "books.xml", "r" );
while( $data = fread( $f, 4096 ) ) { $xml .= $data; }
fclose( $f );
preg_match_all( "/\<book\>(.*?)\<\/book\>/s",
$xml, $bookblocks );
foreach( $bookblocks[1] as $block )
{
preg_match_all( "/\<author\>(.*?)\<\/author\>/",
$block, $author );
preg_match_all( "/\<title\>(.*?)\<\/title\>/",
$block, $title );
preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/",
$block, $publisher );
echo( $title[1][0]." - ".$author[1][0]." - ".
$publisher[1][0]."\n" );
}
?>


请注重这个代码有多短。入手下手时,它把文件读进一个大的字符串。然后用一个 regex 函数读取每一个图书项目。最初用 foreach 轮回,在每一个图书块间轮回,并提掏出 author、title 和 publisher。
那末,缺点在哪呢?利用正则表达式代码读取 XML 的成绩是,它并没先辈行反省,确保 XML 的格局优秀。这意味着在读取之前,没法晓得 XML 是不是格局优秀。并且,有些格局准确的 XML 能够与正则表达式不婚配,所以往后必需修正它们。
我从不建议利用正则表达式读取 XML,然而有时它是兼容性最好的体例,由于正则表达式函数老是可用的。不要用正则表达式读取直接来自用户的 XML,由于没法掌握这类 XML 的格局或布局。应该一向用 DOM 库或 SAX 解析器读取来自用户的 XML。
--------------------------------------------------------------------------------
回页首
用 DOM 编写 XML
读取 XML 只是公式的一局部。该如何编写 XML 呢?编写 XML 最好的体例就是用 DOM。清单 5 显示了 DOM 构建图书 XML 文件的体例。
清单 5. 用 DOM 编写图书 XML
复制代码 代码以下:
<?php
$books = array();
$books [] = array(
"title" => "PHP Hacks",
"author" => "Jack Herrington",
"publisher" => "O"Reilly"
);
$books [] = array(
"title" => "Podcasting Hacks",
"author" => "Jack Herrington",
"publisher" => "O"Reilly"
);
$doc = new DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "books" );
$doc->appendChild( $r );
foreach( $books as $book )
{
$b = $doc->createElement( "book" );
$author = $doc->createElement( "author" );
$author->appendChild(
$doc->createTextNode( $book["author"] )
);
$b->appendChild( $author );
$title = $doc->createElement( "title" );
$title->appendChild(
$doc->createTextNode( $book["title"] )
);
$b->appendChild( $title );
$publisher = $doc->createElement( "publisher" );
$publisher->appendChild(
$doc->createTextNode( $book["publisher"] )
);
$b->appendChild( $publisher );
$r->appendChild( $b );
}
echo $doc->saveXML();
?>


在剧本的顶部,用一些示例图书装入了 books 数组。这个数据可以来自用户也能够来自数据库。
示例图书装入以后,剧本创立一个 new DOMDocument,并把根节点 books 添加到它。然后剧本为每本书的 author、title 和 publisher 创立节点,并为每一个节点添加文本节点。每一个 book 节点的最初一步是从头把它添加到根节点 books。
剧本的末尾用 saveXML 办法把 XML 输入到掌握台。(也能够用 save 办法创立一个 XML 文件。)剧本的输入如清单 6 所示。
清单 6. DOM 构建剧本的输入
复制代码 代码以下:
php e4.php
<?xml version="1.0"?>
<books>
<book>
<author>Jack Herrington</author>
<title>PHP Hacks</title>
<publisher>O"Reilly</publisher>
</book>
<book>
<author>Jack Herrington</author>
<title>Podcasting Hacks</title>
<publisher>O"Reilly</publisher>
</book>
</books>

利用 DOM 的真正价值在于它创立的 XML 老是格局准确的。然而假如不克不及用 DOM 创立 XML 时该怎样办?
--------------------------------------------------------------------------------
回页首
用 PHP 编写 XML
假如 DOM 不成用,可以用 PHP 的文本模板编写 XML。清单 7 显示了 PHP 若何构建图书 XML 文件。
清单 7. 用 PHP 编写图书 XML
复制代码 代码以下:
<?php
$books = array();
$books [] = array(
"title" => "PHP Hacks",
"author" => "Jack Herrington",
"publisher" => "O"Reilly"
);
$books [] = array(
"title" => "Podcasting Hacks",
"author" => "Jack Herrington",
"publisher" => "O"Reilly"
);
?>
<books>
<?php
foreach( $books as $book )
{
?>
<book>
<title><?php echo( $book["title"] ); ?></title>
<author><?php echo( $book["author"] ); ?>
</author>
<publisher><?php echo( $book["publisher"] ); ?>
</publisher>
</book>
<?php
}
?>
</books>


剧本的顶部与 DOM 剧本相似。剧本的底部翻开 books 标志,然后在每一个图书中迭代,创立 book 标志和一切的外部 title、author 和 publisher 标志。
这类办法的成绩是对实体停止编码。为了确保实体编码准确,必需在每一个项目上挪用 htmlentities 函数,如清单 8 所示。
清单 8. 利用 htmlentities 函数对实体编码
复制代码 代码以下:
<books>
<?php
foreach( $books as $book )
{
$title = htmlentities( $book["title"], ENT_QUOTES );
$author = htmlentities( $book["author"], ENT_QUOTES );
$publisher = htmlentities( $book["publisher"], ENT_QUOTES );
?>
<book>
<title><?php echo( $title ); ?></title>
<author><?php echo( $author ); ?> </author>
<publisher><?php echo( $publisher ); ?>
</publisher>
</book>
<?php
}
?>
</books>


这就是用根基的 PHP 编写 XML 的烦人的地方。您觉得本人创立了完善的 XML,然而在试图利用数据的时分,即刻就会发明某些元素的编码不准确。
--------------------------------------------------------------------------------
停止语
XML 四周总有很多夸张的地方和搅浑的地方。然而,其实不像您想像的那末难 ―― 出格是在 PHP 如许优异的言语中。在了解并准确地完成了 XML 以后,就会发明有很多壮大的东西可使用。XPath 和 XSLT 就是如许两个值得研讨的东西。刚开始写页面程序,调试完书中的例子。然后就可以尝试编写留言板了,
作者: 柔情似水    时间: 2015-2-4 04:48
写的比较杂,因为我也是个新手,不当至于大家多多指正。
作者: 深爱那片海    时间: 2015-2-9 15:57
,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。
作者: 愤怒的大鸟    时间: 2015-2-17 10:43
真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,
作者: 莫相离    时间: 2015-2-23 04:42
首先我是坚决反对新手上来就用框架的,因为对底层的东西一点都不了解,造成知识上的真空,会对以后的发展不利。我的观点上手了解下框架就好,代码还是手写。当然啦如果是位别的编程语言的高手的话,这个就另当别论啦。
作者: 因胸联盟    时间: 2015-3-4 15:01
其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎
作者: 只想知道    时间: 2015-3-6 16:50
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)
作者: 若天明    时间: 2015-3-13 04:17
没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。
作者: 仓酷云    时间: 2015-3-16 18:21
找到的的资料很多都是在论坛里的,需要注册,所以我一般没到一个论坛都注册一个id,所有的id都注册成一样的,这样下次再进来的时候就不用重复注册啦。当然有些论坛的某些资料是需要的付费的。
作者: 谁可相欹    时间: 2015-3-17 11:08
实践是检验自己会不会的真理。
作者: 透明    时间: 2015-3-21 18:58
爱上php,他也会爱上你。
作者: 老尸    时间: 2015-3-22 00:10
没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。
作者: 海妖    时间: 2015-3-26 20:19
微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox  支持的不是很好,所以能少用还是少用的好。
作者: 爱飞    时间: 2015-4-4 15:01
使用zendstdio 写代码的的时候,把tab 的缩进设置成4个空格是很有必要的
作者: 小妖女    时间: 2015-4-7 13:10
因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax
作者: 冷月葬花魂    时间: 2015-4-8 09:44
写的比较杂,因为我也是个新手,不当至于大家多多指正。
作者: 再现理想    时间: 2015-4-10 10:11
至于模板嘛,各位高人一直以来就是争论不休,我一只小菜鸟就不加入战团啦,咱们新手还是多学点东西的好。
作者: 小女巫    时间: 2015-4-26 17:19
小鸟是第一次发帖(我习惯潜水的(*^__^*) 嘻嘻……),有错误之处还请大家批评指正,另外,前些日子听人说有高手能用php写驱动程序,真是学无止境,人外有人,天外有天。
作者: 乐观    时间: 2015-4-28 02:12
php里的数组为空的时候是不能拿来遍历的;(这个有点低级啊,不过我刚被这个边界问题墨迹了好长一会)




欢迎光临 仓酷云 (http://ckuyun.com/) Powered by Discuz! X3.2