benmorel / xml-streamer
以低内存消耗将大型XML文件作为DOM节点流式传输
Requires
- php: ^7.4 || ^8.0
- ext-dom: *
- ext-xmlreader: *
Requires (Dev)
- ext-simplexml: *
- php-coveralls/php-coveralls: ^2.4
- phpunit/phpunit: ^8.0 || ^9.0
- vimeo/psalm: 4.29.0
README
以低内存消耗将大型XML文件作为单独的DOM元素流式传输。
安装
此库可以通过 Composer 安装
composer require benmorel/xml-streamer
要求
此库需要
这些扩展默认启用,并且应在大多数PHP环境中可用。
项目状态 & 发布过程
此库处于开发中。
当前版本号格式为 0.x.y
。当引入非破坏性更改(添加新方法、优化现有代码等)时,y
将递增。
当引入破坏性更改时,总是开始新的 0.x
版本周期。
因此,可以将项目锁定到给定的发布周期,例如 0.5.*
。
如果您需要升级到较新的发布周期,请查看 发布历史,了解每个后续 0.x.0
版本引入的更改列表。
快速入门
假设您有一个包含一百万个产品列表的产品源,格式如下
<?xml version="1.0" encoding="UTF-8"?> <feed> <products> <product> <id>1</id> <name>foo</name> ... </product> ... <product> <id>1000000</id> <name>bar</name> ... </product> </products> </feed>
要逐个读取它,请使用 <product>
元素的路径实例化一个 XMLStreamer
use BenMorel\XMLStreamer\XMLStreamer; $streamer = new XMLStreamer('feed', 'products', 'product');
文档中与该路径不匹配的任何元素都将被忽略。
然后您可以使用生成器继续流式传输文件,该生成器将为每个 <product>
生成一个 DOMElement 对象
foreach ($streamer->stream('product-feed.xml') as $product) { /** @var DOMElement $product */ echo $product->getElementsByTagName('name')->item(0)->textContent; // foo, ..., bar }
使用SimpleXML查询
如果您更愿意使用SimpleXML,可以使用 simplexml_import_dom()。SimpleXML要求在导入之前将元素包装在 DOMDocument
中
foreach ($streamer->stream('product-feed.xml') as $product) { /** @var DOMElement $product */ $document = new \DOMDocument(); $document->appendChild($product); $element = simplexml_import_dom($product); echo $element->name; // foo, ..., bar }
这需要默认启用的 SimpleXML 扩展。
返回值
处理完所有元素后,生成器返回流式传输的元素数
$products = $streamer->stream('product-feed.xml'); foreach ($products as $product) { /* ... */ } $productCount = $products->getReturn();
配置选项
限制元素数量
如果您只需要获取XML文件的预览,可以设置要流式传输的最大元素数量
$streamer->setMaxElements(10);
使用此配置,XMLStreamer
将最多产生10个元素,并忽略进一步的条目。
配置编码
源文件的编码自动从XML声明中读取
<?xml version="1.0" encoding="UTF-8"?>
如果您的XML文件缺少 encoding
,您可以手动指定它
$streamer->setEncoding('ISO-8859-1');
请注意,这仅指定输入文件编码。输出 DOMElement
总是UTF-8。
错误处理
如果在任何点发生错误(错误打开或读取文件、文档格式不正确),则抛出 XMLReaderException
。
请注意,在抛出异常时可能已经开始流式传输,因此生成器可能已经产生了多个元素。