用 PHP 读取 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> |
使用 DOM 库读取 XML
读取格式良好的 XML 文件最容易的方式是使用编译成某些 PHP 安装的文档对象模型 (DOM)库。DOM 库把整个 XML 文档读入内存,并用节点树表示它。
图 1. 图书 XML 的 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。
转载于:https://blog.51cto.com/zdkhome/1216820
用 PHP 读取 XML相关推荐
- android读取xml 字符串,Android 读取本地Xml文件,并转换成String
问题 不是解析本地 xml 文件, 而是要将 xml 文件中的所有内容(包含格式,标签等),直接转换成 String. 与前端H5页面交互时, iOS 在请求远程 xml 文件耗时太长(有时需要4~5 ...
- SQL Server中读取XML文件的简单做法
SQL Server 2000使得以XML导出数据变得更加简单,但在SQL Server 2000中导入XML数据并对其进行处理则有些麻烦.本文介绍在SQL Server中读取XML文件的简单做法. ...
- 【OpenCV 4开发详解】保存和读取XML和YMAL文件
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...
- 在asp.net中读取XML文件信息的4种方法
方法一 :使用XML控件 <% @ Page Language="C#"%> <html> <body> <h3 ...
- [转帖]C#执行SQL脚本,读取XML文件
[转帖]C#执行SQL脚本,读取XML文件 需要添加如下引用: using System.IO; using System.Data.SqlClient; using System.Collectio ...
- java 存取xml数据_JAVA读取XML文件数据
XML文档内容如下: title1 title2 title3 JAVA代码如下: package cn.mylucene; import java.io.File; import java.io.I ...
- 在C#中使用XML指南之读取XML
对于XML,想必各位都比较了解,我也就不用费笔墨来描述它是什么了,我想在未来的Web开发中XML一定会大放异彩,XML是可扩展标记语言,使用它企业可以制定一套自己的数据格式,数据按照这种格式在网络中传 ...
- C#中读取xml文件指定节点
假设xml文件内容是 <?xml version="1.0" encoding="utf-8"?> <Workflow> <A ...
- 利用opencv中的类FileStorage生成和读取XML和YAML文件
有时候程序中的变量值.字符串.数组等数据也需要独立于源代码本身保存,这个时候就需要用到XML和YAML文件进行保存. OpenCV4提供了用于生成和读取XML文件和YAML文件的类FileStorag ...
- java读取XML文件的四种方式
java读取XML文件的四种方式 Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT& ...
最新文章
- Moss/Sharepoint 一些很重要的API备忘
- java编程题库下载_Java习题
- Effective_STL 学习笔记(十九) 了解相等和等价的区别
- 【APIO2018】Duathlon 铁人两项 【圆方树】
- c语言 写高斯分布函数
- java gui 数独_数独-GUI开发
- linux计划任务详解(附演示)
- Kindle 2 初探
- @submit.native.prevent的作用?
- 使用亚马逊云快速托管静态网站
- python中的列表
- HTML基础DW使用教程
- 15个Android流行框架
- 网上流传的《名侦探柯南》大结局十二种!
- 解决 chrome 37 之后 flash 版本过低问题
- B+树真的不难,楼下菜大爷都能学得会的B+树!(数据结构可视化神器推荐)
- warn_alloc():page allocation failure问题分析
- 20221119 今天的世界发生了什么
- linux第三方软件安装目录
- matplotlib:marker类型/size/空心
热门文章
- MDX 中的重要概念 (MDX)
- linuex查看繁忙_如何用九条命令在一分钟内检查Linux服务器性能?
- 11.PHP与MySQL
- C#-CHTTPDownload
- C#-Stmp发邮件
- Intel汇编语言程序设计学习-第三章 汇编语言基础-下
- 【Groovy】MOP 元对象协议与元编程 ( 方法注入 | 使用 ExpandoMetaClass 进行方法注入 )
- 【错误记录】安装 Visual Studio 2013 中文语言包报错 ( 需要 Microsoft Visual Studio Test Agent , 但此计算机上并为安装它 )
- GIL(全局解释器锁)与互斥锁
- 前端读者 | 别人写的css,你敢用吗?