A coroutine example: Streaming XML parsing using xml_parser
<?php error_reporting(E_ALL); /* Data can be send to coroutines using `$coroutine->send($data)`. The sent data will then
* be the result of the `yield` expression. Thus it can be received using a code like
* `$data = yield;`.
*/ /* What we're building in this script is a coroutine-based streaming XML parser. The PHP
* extension for parsing streamed XML is xml_parser. It is used by defining a set of
* callback functions for various events (like start tag, end tag, content).
*
* This event model makes the parsing process very complicated, because you basically
* have to implement your own state machine (which is a lot of boilerplate code the
* more complicated the XML gets).
*
* To solve this problem, we build a wrapper (the following function), which redirects
* the events to a coroutine ($target). This is done simply using
* `$target->send([$eventName, $data])`.
*/
function streamingXMLParser($target) {
$xmlParser = xml_parser_create();
xml_set_element_handler(
$xmlParser,
function ($xmlParser, $name, array $attributes) use ($target) {
$target->send(['start', [$name, $attributes]]);
},
function ($xmlParser, $name) use ($target) {
$target->send(['end', $name]);
}
);
xml_set_character_data_handler(
$xmlParser,
function ($xmlParser, $text) use ($target) {
$target->send(['text', $text]);
}
); while ($data = yield) {
if (!xml_parse($xmlParser, $data)) {
throw new Exception(sprintf(
'XML error "%s" on line %d',
xml_error_string(xml_get_error_code($xmlParser)),
xml_get_current_line_number($xmlParser)
));
}
} xml_parser_free($xmlParser);
} /* Inside the target coroutine the actual parsing happens. The events are received
* using `list($event, $data) = yield`. The main advantage that coroutines bring
* here is that you can fetch the events in nested loops. This way you are implicitly
* building a state machine (but the state is managed by PHP, not you!)
*
* This particular coroutine parses bus location data (for samples scroll down). The
* result is passed to another $target coroutine.
*/
function busXMLParser($target) {
while (true) {
list($event, $data) = yield;
if ($event == 'start' && $data[0] == 'BUS') {
$dict = [];
$content = '';
while (true) {
list($event, $data) = yield;
if ($event == 'start') {
$content = '';
} elseif ($event == 'text') {
$content .= $data;
} elseif ($event == 'end') {
if ($data == 'BUS') {
$target->send($dict);
break;
} $dict[strtolower($data)] = $content;
}
}
}
}
} /* This coroutine prints out the info it receives from the bus XML parser. */
function busLocationPrinter() {
while (true) {
$data = yield;
echo "Bus $data[id] is currently at $data[latitude]/$data[longitude]\n";
}
} /* Here we are building up a coroutine pipeline. You should read this as:
* The streaming XML parser is passing data to the bus XML parser, which
* is passing data to the bus location printer.
*/
$parser = streamingXMLParser(busXMLParser(busLocationPrinter())); /* I don't have access to a real bus location API, so I'll just stream some
* fictional sample data */
$parser->send('<?xml version="1.0"?><buses>');
while (true) {
sleep(1);
$parser->send(sprintf(
'<bus><id>%d</id><latitude>%f</latitude><longitude>%f</longitude></bus>',
mt_rand(1, 1000), lcg_value(), lcg_value()
));
} /* If your head is buzzing now, that's a good thing :P */
A coroutine example: Streaming XML parsing using xml_parser的更多相关文章
- Dreamweaver无法启动:xml parsing fatal error..Designer.xml错误解决方法
xml parsing fatal error:Invalid document structure,line:1,file:C:\Documents and Settings\Administrat ...
- XML Parsing Error: no element found Location: moz-nullprincipal:{23686e7a-652b-4348-92f4-7fb3575179ed} Line Number 1, Column 1:^
“Hi Insus.NET, 我有参考你下午发布的一篇<jQuery.Ajax()执行WCF Service的方法>http://www.cnblogs.com/insus/p/37278 ...
- 解决org.apache.jasper.JasperException: org.apache.jasper.JasperException: XML parsing error on file org.apache.tomcat.util.scan.MergedWebXml
1.解决办法整个项目建立时采用utf-8编码,包括代码.jsp.配置文件 2.并用最新的tomcat7.0.75 相关链接: http://ask.csdn.net/questions/223650
- Parsing XML in J2ME
sun的原文,原文地址是http://developers.sun.com/mobility/midp/articles/parsingxml/. by Jonathan KnudsenMarch 7 ...
- 【Java】Java XML 技术专题
XML 基础教程 XML 和 Java 技术 Java XML文档模型 JAXP(Java API for XML Parsing) StAX(Streaming API for XML) XJ(XM ...
- iphone Dev 开发实例8: Parsing an RSS Feed Using NSXMLParser
From : http://useyourloaf.com/blog/2010/10/16/parsing-an-rss-feed-using-nsxmlparser.html Structure o ...
- php判断字符串是不是xml格式并解析
最近遇到要要判断一个字符串是不是xml格式,网上找到一段代码,试了一下,完全可行 /** * 解析XML格式的字符串 * * @param string $str ...
- Java解析XML文档(简单实例)——dom解析xml
一.前言 用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object ...
- javascript-处理XML
/** * Created by Administrator on 2015/4/4. */ var XmlUtil=(function () { var createDocument= functi ...
随机推荐
- 【FOL】第三周
这周还是在改自己的这个框架,被多线程折腾了两天,最终无奈放弃在游戏启动时调用引擎进行图片相关资源的初始化,当然进展还是不错的. 嗯,下面还是以流水的方式继续记录一下本周完成的工作: 1.调通了客户端与 ...
- Spring面试基本问题(1)
1.什么是Spring框架?Spring框架有哪些主要模块? Spring框架是一个为Java应用程序的开发提供了综合.广泛的基础性支持的Java平台.Spring帮助开发者解决了开发中基础性的问题, ...
- CentOS安装zip unzip命令
yum install zip unzip
- Nodejs与ES6系列4:ES6中的类
ES6中的类 4.1.class基本语法 在之前的javascript语法中是不存在class这样的概念,如果要通过构造函数生成一个新对象代码 function Shape(width,height) ...
- Ajax+PHP+MySQL 登陆示例
PHP是一门很好的语言,可以很方便的开发web应用程序,下面介绍一下PHP如何通过AJAX方式实现登录功能: 1 login.php 登录界面中,javascript脚本用ajax方式异步请求dolo ...
- Reapp - 下一代的 Hybrid App 开发框架
Reapp 与 React Native 有着惊人的相似之处,二者都使用 React 来创建应用程序用户界面的框架.然而,在底层机制上这两个框架之间却具有明显的哲学差异.React Native 将 ...
- 【前端盲点】DOM事件流论证CSS盒模型是否具有厚度
前言 很久没有扯淡了,我们今天来扯淡吧. 我今天思考了一个问题,我们页面的dom树到底是如何渲染的,而CSS盒模型与javascript是否有联系,于是便想到一个问题: CSS的盒模型具有厚度么??? ...
- 【初探移动前端开发04】jQuery Mobile (中)
前言 昨天我们一起学习了一部分jquery mobile的知识,今天我们继续. 这些是些很基础的东西,有朋友觉得这个没有其它的好,但是学习下不吃亏嘛,我反正也不会一起学习基础啦. 例子请使用手机查看哦 ...
- html5标签的改变
1.新的文档类型声明 浏览器解析html模式是有两种模式,按照各自浏览器的定义渲染的页面叫“怪异模式”,而按照w3c组织统一的标准渲染叫“标准模式”.一般都是使用标准模式来保持网页兼容性,区分这两种模 ...
- 实现a标签中的各种点击(onclick)事件的方法
我们常用的在a标签中有点击事件:1. a href="javascript:js_method();"这是我们平台上常用的方法,但是这种方法在传递this等参数的时候很容易出问题, ...