PHP读取和编写XMLDOM文档格式.docx
- 文档编号:16550910
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:10
- 大小:20.03KB
PHP读取和编写XMLDOM文档格式.docx
《PHP读取和编写XMLDOM文档格式.docx》由会员分享,可在线阅读,更多相关《PHP读取和编写XMLDOM文档格式.docx(10页珍藏版)》请在冰豆网上搜索。
first
last
属性:
<name
first="
Jack"
last="
Herrington"
也可以用
对特殊字符进行编码。
例如,&
符号可以像这样编码:
&
包含标记和属性的
文件如果像示例一样格式化,就是格式良好的,这意味着标记是对称的,字符的编码正确。
清单
1
是一份格式良好的
的示例。
清单
1.
图书列表示例
<books>
<book>
<author>Jack
Herrington</author>
<title>PHP
Hacks</title>
<publisher>O'
Reilly</publisher>
</book>
<title>Podcasting
</books>
中的
包含一个图书列表。
父标记
<books>
包含一组
<book>
标记,每个
标记又包含
<author>、<title>
<publisher>
标记。
当
文档的标记结构和内容得到外部模式文件的验证后,XML
文档就是正确的。
模式文件可以用不同的格式指定。
对于本文来说,所需要的只是格式良好的
如果觉得
看起来很像超文本标记语言(HTML),那么就对了。
HTML
都是基于标记的语言,它们有许多相似之处。
但是,要着重指出的是:
虽然
文档可能是格式良好的
HTML,但不是所有的
文档都是格式良好的
换行标记(br)是
之间区别的一个好例子。
这个换行标记是格式良好的
HTML,但不是格式良好的
<p>This
is
a
paragraph<br>
With
line
break</p>
这个换行标记是格式良好的
HTML:
paragraph<br
如果要把
编写成同样是格式良好的
XML,请遵循
W3C
委员会的可扩展超文本标记语言(XHTML)标准(参见
参考资料)。
所有现代的浏览器都能呈现
XHTML。
而且,还可以用
工具读取
XHTML
并找出文档中的数据,这比解析
容易得多。
使用
库读取
XML
读取格式良好的
文件最容易的方式是使用编译成某些
安装的文档对象模型
(DOM)库。
库把整个
文档读入内存,并用节点树表示它,如图
所示。
图
图书
的
树
<
img
src="
onclick="
get_larger(this)"
/>
树顶部的
books
节点有两个
book
子标记。
在每本书中,有
author、publisher
title
几个节点。
节点分别有包含文本的文本子节点。
读取图书
文件并用
显示内容的代码如清单
2
2.
用
读取图书
<?
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
publisher"
$publisher
$publishers->item(0)->nodeValue;
$titles
title"
$title
$titles->item(0)->nodeValue;
echo
$title
-
$author
$publisher
;
}
?
> 脚本首先创建一个
DOMdocument
对象,用
load
方法把图书
装入这个对象。
之后,脚本用
getElementsByName
方法得到指定名称下的所有元素的列表。
在
节点的循环中,脚本用
方法获得
标记的
nodeValue。
nodeValue
是节点中的文本。
脚本然后显示这些值。
可以在命令行上像这样运行
脚本:
%
php
e1.php
PHP
Hacks
Herrington
O'
Reilly
Podcasting
%
可以看到,每个图书块输出一行。
这是一个良好的开始。
但是,如果不能访问
库该怎么办?
解析器读取
读取
的另一种方法是使用
Simple
API(SAX)解析器。
的大多数安装都包含
解析器。
解析器运行在回调模型上。
每次打开或关闭一个标记时,或者每次解析器看到文本时,就用节点或文本的信息回调用户定义的函数。
SAX
解析器的优点是,它是真正轻量级的。
解析器不会在内存中长期保持内容,所以可以用于非常巨大的文件。
缺点是编写
解析器回调是件非常麻烦的事。
3
显示了使用
文件并显示内容的代码。
3.
解析器读取图书
$g_books
array();
$g_elem
null;
function
startElement(
$parser,
$name,
$attrs
)
global
$g_books,
$g_elem;
if
(
$name
==
BOOK'
)
$g_books
[]=
$name;
endElement(
textData(
$text
$g_elem
AUTHOR'
||
PUBLISHER'
TITLE'
$g_books[
count(
][
]
$text;
$parser
xml_parser_create();
xml_set_element_handler(
startElement"
endElement"
xml_set_character_data_handler(
textData"
$f
fopen(
r'
while(
$data
fread(
$f,
4096
xml_parse(
xml_parser_free(
$parser
$book['
]."
.$book['
>
脚本首先设置
g_books
数组,它在内存中容纳所有图书和图书信息,g_elem
变量保存脚本目前正在处理的标记的名称。
然后脚本定义回调函数。
在这个示例中,回调函数是
startElement、endElement
textData。
在打开和关闭标记的时候,分别调用
startElement
endElement
函数。
在开始和结束标记之间的文本上面,调用
在这个示例中,startElement
标记查找
标记,在
数组中开始一个新元素。
然后,textData
函数查看当前元素,看它是不是
publisher、title
或
author
如果是,函数就把当前文本放入当前图书。
为了让解析继续,脚本用
xml_parser_create
函数创建解析器。
然后,设置回调句柄。
之后,脚本读取文件并把文件的大块内容发送到解析器。
在文件读取之后,xml_parser_free
函数删除解析器。
脚本的末尾输出
数组的内容。
可以看到,这比编写
的同样功能要困难得多。
如果没有
库也没有
还有替代方案么?
用正则表达式解析
可以肯定,即使提到这个方法,有些工程师也会批评我,但是确实可以用正则表达式解析
4
preg_
函数读取图书文件的示例。
4.
用正则表达式读取
$xml
{
$xml
.=
$data;
}
fclose(
$f
preg_match_all(
/<book>(.*?
)</book>/s"
$xml,
$bookblocks
$bookblocks[1]
$block
/<author>(.*?
)</author>/"
$block,
/<title>(.*?
)</title>/"
/<publisher>(.*?
)</publisher>/"
$publisher
echo(
$title[1][0]."
.$author[1][0]."
.
$publisher[1][0]."
请注意这个代码有多短。
开始时,它把文件读进一个大的字符串。
然后用一个
regex
函数读取每个图书项目。
最后用
foreach
循环,在每个图书块间循环,并提取出
author、title
publisher。
那么,缺陷在哪呢?
使用正则表达式代码读取
的问题是,它并没先进行检查,确保
的格式良好。
这意味着在读取之前,无法知道
是否格式良好。
而且,有些格式正确的
可能与正则表达式不匹配,所以日后必须修改它们。
我从不建议使用正则表达式读取
XML,但是有时它是兼容性最好的方式,因为正则表达式函数总是可用的。
不要用正则表达式读取直接来自用户的
XML,因为无法控制这类
的格式或结构。
应当一直用
库或
解析器读取来自用户的
编写
只是公式的一部分。
该怎样编写
呢?
最好的方式就是用
DOM。
5
显示了
构建图书
文件的方式。
5.
编写图书
[]
array(
'
title'
=>
Hacks'
author'
Herrington'
publisher'
Reilly"
);
Podcasting
$doc->formatOutput
true;
$r
$doc->createElement(
books"
$doc->appendChild(
$r
$b
$author->appendChild(
$doc->createTextNode(
$b->appendChild(
$title->appendChild(
$publisher->appendChild(
$r->appendChild(
$b
$doc->saveXML();
在脚本的顶部,用一些示例图书装入了
数组。
这个数据可以来自用户也可以来自数据库。
示例图书装入之后,脚本创建一个
DOMDocument,并把根节点
添加到它。
然后脚本为每本书的
publisher
创建节点,并为每个节点添加文本节点。
每个
节点的最后一步是重新把它添加到根节点
books。
脚本的末尾用
saveXML
方法把
输出到控制台。
(也可以用
save
方法创建一个
文件。
)脚本的输出如清单
6
6.
构建脚本的输出
%
e4.php
xml
version="
1.0"
?
%
的真正价值在于它创建的
总是格式正确的。
但是如果不能用
创建
时该怎么办?
如果
不可用,可以用
的文本模板编写
7
如何构建图书
7.
<title><?
echo(
></title>
<author><?
</author>
<publisher><?
</publisher>
脚本的顶部与
脚本类似。
脚本的底部打开
标记,然后在每个图书中迭代,创建
标记和所有的内部
title、author
这种方法的问题是对实体进行编码。
为了确保实体编码正确,必须在每个项目上调用
htmlentities
函数,如清单
8
8.
函数对实体编码 <books>
htmlentities(
],
ENT_QUOTES
>
</author>
这就是用基本的
的烦人之处。
您以为自己创建了完美的
XML,但是在试图使用数据的时候,马上就会发现某些元素的编码不正确。
结束语
周围总有许多夸大之处和混淆之处。
但是,并不像您想像的那么难
特别是在
这样优秀的语言中。
在理解并正确地实现了
之后,就会发现有许多强大的工具可以使用。
XPath
XSLT
就是这样两个值得研究的工具
appendChild添加一个子结点到指定的XML元素
-attributesXML元素的属性数组
-childNodes一个XML元素的子结点数组
-cloneNode克隆(复制)当前结点
-createElement新建一个新的XML元素
-createTextNode新建一个新的XML文本结点
-firstChild返回当前XML结点的第一个子结点
-hasChildNodes当前XML结点是否有子结点(返回true有子结点/flash则无)
-insertBefore在一个指定的XML元素的子结点前插入一个新的子结点
-lastChild返回当前XML结点的最后一个子结点
-load从指定的URL把XML元素引入FLASH中
-loaded当XML元素引入或是发送同时引入FLASH中后,返回true值
-newXML新建一个XML对象
-nextSibling当前XML结点的下一个结点
-nodeName返回当前XML结点的名字
-nodeType返回当前XML结点的类型(1-元素,3-文本)
-nodevalue返回当前XML结点的值(text型返回文本)
-onLoad当引入或发送同时引入时触发事件
-parentNode返回当前XML结点的父结点
-parseXML将XML字符串转换成XML对象
-previousSibling当前XML结点的前一个结点
-removeNode从XML文本中删除结点
-send从FLASH中把一个XML元素发送到指定的URL地址
-sendAndLoad从FLASH中把一个XML元素发送到指定的URL地址同时引入XML结果
-toString把XML对象转换为XML字符串表达
+XMLSocketXML套接口
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PHP 读取 编写 XMLDOM