benmorel/xml-streamer

以低内存消耗将大型XML文件作为DOM节点流式传输

资助包维护!
BenMorel

0.5.0 2022-11-01 12:45 UTC

This package is auto-updated.

Last update: 2024-09-03 22:02:56 UTC


README

以低内存消耗将大型XML文件作为单独的DOM元素流式传输。

Build Status Coverage Status Latest Stable Version License

安装

此库可以通过 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

请注意,在抛出异常时可能已经开始流式传输,因此生成器可能已经产生了多个元素。