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 ...
随机推荐
- 《Java4Android》视频学习笔记——包和访问权限(一)
怎么打包?代码如下 package org.marsdroid; class Test{ public static void main(String args[]){ System.out.prin ...
- mysql数据过滤
WHERE子句 在我们使用数据库时,通常只会根据特定条件提取表数据的子集.只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filtercondition). ...
- 为mongodb数据库添加安全账户
最近的数据库服务器有些不稳定,遇到了黑客的骚扰,mongodb的安全存在一些漏洞.首要任务是给数据库添加账号.之前大家都习惯于mongodb的不加安全账号和密码来连接数据库,那么问题是添加了安全账户后 ...
- 第2章 如何构建布局良好的Windows程序
01.菜单栏(MenuStrip) 设置快捷键方式: 方式一:1.设置菜单项的Text属性为(打开(&F)), 首先必须按住alt+主菜单快捷键进入到对应的主菜单, 然后直接按F就可以打开子窗 ...
- jshint配置(js检查)
JSHint的选项配置 asi 如果是真,JSHint会无视没有加分号的行尾,自动补全分号一直是Javascript很有争议的一个语法特性.默认,JSHint会要求你在每个语句后面加上分号,但是如果你 ...
- Quartz.NET开源作业调度框架系列(二):CronTrigger
CronTriggers比SimpleTrigger更加的灵活和有用,对于比较复杂的任务触发规则,例如"每个星期天的晚上12:00"进行备份任务,SimpleTrigger就不能胜 ...
- [deviceone开发]-一个很炫的手势动画示例
一.简介 这是iOS下的效果,android下完全一致.通过do_GestureView组件和do_Animation组件,deviceone能很容易实现复杂的跨平台纯原生动画效果,这个示例就是通过手 ...
- scroll事件实现监控滚动条并分页显示示例(zepto.js)
scroll事件实现监控滚动条并分页显示示例(zepto.js ) 需求:在APP落地页上的底部位置显示此前其他用户的购买记录,要求此div盒子只显示3条半,但一页有10条,div内的滑动条滑到一页 ...
- Swiper教程 —— 使用方法
Swiper使用方法 1.首先加载插件,需要用到的文件有swiper.min.js和swiper.min.css文件. <!DOCTYPE html> <html> <h ...
- 每天checklist所用到的T-CODE
1.1重点检查 作业 事务码 检查过程 检查R/3系统是否已经启动 · 登录到R/3系统 检查每日备份是否正常 DB12-Backup Logs:Overview · 检查数据库备份 · 检查数据库备 ...