PHPackages                             prewk/xml-string-streamer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. prewk/xml-string-streamer

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

prewk/xml-string-streamer
=========================

Stream large XML files with low memory consumption

1.2.3(3y ago)3603.1M—3.2%49[10 issues](https://github.com/prewk/xml-string-streamer/issues)19MITPHPPHP ^7.2 || ^8.0

Since Apr 27Pushed 3y ago17 watchersCompare

[ Source](https://github.com/prewk/xml-string-streamer)[ Packagist](https://packagist.org/packages/prewk/xml-string-streamer)[ Docs](https://github.com/prewk/xml-string-streamer)[ RSS](/packages/prewk-xml-string-streamer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (3)Versions (41)Used By (19)

xml-string-streamer [![Build Status](https://camo.githubusercontent.com/c3f25917bfd865bfecbd0b2b9ed247156a6f50865ac46e49ad9e8b14991d2426/68747470733a2f2f6170692e7472617669732d63692e6f72672f707265776b2f786d6c2d737472696e672d73747265616d65722e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/prewk/xml-string-streamer)
======================================================================================================================================================================================================================================================================================================================================

[](#xml-string-streamer-)

Purpose
-------

[](#purpose)

To stream XML files too big to fit into memory, with very low memory consumption. This library is a successor to [XmlStreamer](https://github.com/prewk/XmlStreamer).

Installation
------------

[](#installation)

### Legacy support

[](#legacy-support)

- All versions below 1 support PHP 5.3 - 7.2
- Version 1 and above support PHP 7.2+

### With composer

[](#with-composer)

Run `composer require prewk/xml-string-streamer` to install this package.

Usage
-----

[](#usage)

Let's say you have a 2 GB XML file gigantic.xml containing customer items that look like this:

```

        Jane
        Doe

    ...

```

Create a streamer and parse it:

```
// Convenience method for creating a file streamer with the default parser
$streamer = Prewk\XmlStringStreamer::createStringWalkerParser("gigantic.xml");

while ($node = $streamer->getNode()) {
    // $node will be a string like this: "JaneDoe"
    $simpleXmlNode = simplexml_load_string($node);
    echo (string)$simpleXmlNode->firstName;
}
```

Without the convenience method (functionally equivalient):

```
use Prewk\XmlStringStreamer;
use Prewk\XmlStringStreamer\Stream;
use Prewk\XmlStringStreamer\Parser;

// Prepare our stream to be read with a 1kb buffer
$stream = new Stream\File("gigantic.xml", 1024);

// Construct the default parser (StringWalker)
$parser = new Parser\StringWalker();

// Create the streamer
$streamer = new XmlStringStreamer($parser, $stream);

// Iterate through the `` nodes
while ($node = $streamer->getNode()) {
    // $node will be a string like this: "JaneDoe"
    $simpleXmlNode = simplexml_load_string($node);
    echo (string)$simpleXmlNode->firstName;
}
```

Convenience method for the UniqueNode parser:

```
$streamer = Prewk\XmlStringStreamer::createUniqueNodeParser("file.xml", array("uniqueNode" => "customer"));
```

Parsers
-------

[](#parsers)

### Parser\\StringWalker

[](#parserstringwalker)

Works like an XmlReader, and walks the XML tree node by node. Captures by node depth setting.

### Parser\\UniqueNode

[](#parseruniquenode)

A much faster parser that captures everything between a provided element's opening and closing tags. Special prerequisites apply.

Stream providers
----------------

[](#stream-providers)

### Stream\\File

[](#streamfile)

Use this provider to parse large XML files on disk. Pick a chunk size, for example: 1024 bytes.

```
$CHUNK_SIZE = 1024;
$provider = new Prewk\XmlStringStreamer\Stream\File("large-xml-file.xml", $CHUNK_SIZE);
```

### Stream\\Stdin

[](#streamstdin)

Use this provider if you want to create a CLI application that streams large XML files through STDIN.

```
$CHUNK_SIZE = 1024;
$fsp = new Prewk\XmlStringStreamer\Stream\Stdin($CHUNK_SIZE);
```

### Stream\\Guzzle

[](#streamguzzle)

Use this provider if you want to stream over HTTP with [Guzzle](https://github.com/guzzle/guzzle). Resides in its own repo due to its higher PHP version requirements (5.5):

StringWalker Options
--------------------

[](#stringwalker-options)

### Usage

[](#usage-1)

```
use Prewk\XmlStringStreamer;
use Prewk\XmlStringStreamer\Parser;
use Prewk\XmlStringStreamer\Stream;

$options = array(
    "captureDepth" => 3
);

$parser = new Parser\StringWalker($options);
```

### Available options for the StringWalker parser

[](#available-options-for-the-stringwalker-parser)

OptionDefaultDescription(int) captureDepth`2`Depth we start collecting nodes at(array) tagsSee exampleSupported tags(bool) expectGT`false`Whether to support `>` in XML comments/CDATA or not(array) tagsWithAllowedGTSee exampleIf *expectGT* is `true`, this option lists the tags with allowed `>` characters in them### Examples

[](#examples)

#### captureDepth

[](#capturedepth)

Default behavior with a capture depth of `2`:

```

        ...

        ...

```

..will capture the `` nodes.

But say your XML looks like this:

```

            ...

            ...

```

Then you'll need to set the capture depth to `3` to capture the `` nodes.

Node depth visualized:

```

```

#### tags

[](#tags)

Default value:

```
array(
    array("", 0),
    array("", 0),
    array("", "]]>", 0),
    array("", ">", 0),
    array("", -1),
    array("", 0),
    array("", 1)
),
```

First parameter: opening tag, second parameter: closing tag, third parameter: depth.

If you know that your XML doesn't have any XML comments, CDATA or self-closing tags, you can tune your performance by setting the *tags* option and omitting them:

```
array(
    array("", 0),
    array("", ">", 0),
    array("", -1),
    array("", 1)
),
```

#### expectGT &amp; tagsWithAllowedGT

[](#expectgt--tagswithallowedgt)

You can allow the `>` character within XML comments and CDATA sections if you want. This is pretty uncommon, and therefore turned off by default for performance reasons.

Default value for tagsWithAllowedGT:

```
array(
    array(""),
    array("", "]]>")
),
```

UniqueNode Options
------------------

[](#uniquenode-options)

### Usage

[](#usage-2)

```
use Prewk\XmlStringStreamer;
use Prewk\XmlStringStreamer\Parser;
use Prewk\XmlStringStreamer\Stream;

$options = array(
    "uniqueNode" => "TheNodeToCapture"
);

$parser = new Parser\UniqueNode($options);
```

### Available options for the UniqueNode parser

[](#available-options-for-the-uniquenode-parser)

OptionDescription(string) uniqueNodeRequired option: Specify the node name to capture(bool) checkShortClosingWhether to check short closing tag or not### Examples

[](#examples-1)

#### uniqueNode

[](#uniquenode)

Say you have an XML file like this:

```

        ...

        ...

        ...

```

You want to capture the stuff nodes, therefore set *uniqueNode* to `"stuff"`.

If you have an XML file with short closing tags like this:

```

        ...

```

You want to capture the stuff nodes, therefore set *uniqueNode* to `"stuff"` and *checkShortClosing* to `true`.

But if your XML file look like this:

```

        Lorem ipsum

            Oops, another stuff node

    ...

```

..you won't be able to use the UniqueNode parser, because `` exists inside of another `` node.

Advanced Usage
--------------

[](#advanced-usage)

### Progress bar

[](#progress-bar)

You can track progress using a closure as the third argument when constructing the stream class. Example with the `File` stream using the `StringWalker` parser:

```
use Prewk\XmlStringStreamer;
use Prewk\XmlStringStreamer\Stream\File;
use Prewk\XmlStringStreamer\Parser\StringWalker;

$file = "path/to/file.xml";

// Save the total file size
$totalSize = filesize($file);

// Construct the file stream
$stream = new File($file, 16384, function($chunk, $readBytes) use ($totalSize) {
    // This closure will be called every time the streamer requests a new chunk of data from the XML file
    echo "Progress: $readBytes / $totalSize\n";
});
// Construct the parser
$parser = new StringWalker;

// Construct the streamer
$streamer = new XmlStringStreamer($parser, $stream);

// Start parsing
while ($node = $streamer->getNode()) {
    // ....
}
```

*You could of course do something more intelligent than spamming with `echo`.*

### Accessing the root element (version 0.7.0+)

[](#accessing-the-root-element-version-070)

Setting the parser option `extractContainer` tells the parser to gather everything before and after your intended child element capture. The results are available via the parser's `getExtractedContainer()` method.

*Note:* `getExtractedContainer()` will return different things depending on if you've streamed the whole file or not. If you need the containing XML data prematurely you can get it inside of the while loop, but it will just be the opening elements and therefore considered invalid XML by parsers such as SimpleXML.

```
use Prewk\XmlStringStreamer;
use Prewk\XmlStringStreamer\Stream\File;
use Prewk\XmlStringStreamer\Parser\StringWalker;

$file = "path/to/file.xml";

// Construct the file stream
$stream = new File($file, 16384);
// Construct the parser
$parser = new StringWalker(array(
    "extractContainer" => true, // Required option
));

// Construct the streamer
$streamer = new XmlStringStreamer($parser, $stream);

// Start parsing
while ($node = $streamer->getNode()) {
    // ....
}

// Get the containing XML
$containingXml = $parser->getExtractedContainer();

$xmlObj = simplexml_load_string($containingXml);
$rootElementName = $xmlObj->getName();
$rootElementFooAttribute = $xmlObj->attributes()->foo;
```

*This method should be considered experimental, and may extract weird stuff in edge cases*

###  Health Score

53

—

FairBetter than 97% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity62

Solid adoption and visibility

Community38

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 87.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~85 days

Recently: every ~181 days

Total

39

Last Release

1172d ago

Major Versions

0.14.0 → 1.0.02020-12-14

PHP version history (3 changes)0.0.4PHP &gt;=5.3.0

0.10.0PHP &gt;=5.3

1.0.0PHP ^7.2 || ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/640102?v=4)[Oskar Thornblad](/maintainers/prewk)[@prewk](https://github.com/prewk)

---

Top Contributors

[![prewk](https://avatars.githubusercontent.com/u/640102?v=4)](https://github.com/prewk "prewk (112 commits)")[![snapshotpl](https://avatars.githubusercontent.com/u/312655?v=4)](https://github.com/snapshotpl "snapshotpl (3 commits)")[![mkraemer](https://avatars.githubusercontent.com/u/1070200?v=4)](https://github.com/mkraemer "mkraemer (2 commits)")[![bs-thomas](https://avatars.githubusercontent.com/u/2464920?v=4)](https://github.com/bs-thomas "bs-thomas (1 commits)")[![dominik-vasicek](https://avatars.githubusercontent.com/u/57711297?v=4)](https://github.com/dominik-vasicek "dominik-vasicek (1 commits)")[![friartuck6000](https://avatars.githubusercontent.com/u/4365821?v=4)](https://github.com/friartuck6000 "friartuck6000 (1 commits)")[![hannesvdvreken](https://avatars.githubusercontent.com/u/1410358?v=4)](https://github.com/hannesvdvreken "hannesvdvreken (1 commits)")[![animir](https://avatars.githubusercontent.com/u/4623196?v=4)](https://github.com/animir "animir (1 commits)")[![jDolba](https://avatars.githubusercontent.com/u/2221925?v=4)](https://github.com/jDolba "jDolba (1 commits)")[![Nemo64](https://avatars.githubusercontent.com/u/1749936?v=4)](https://github.com/Nemo64 "Nemo64 (1 commits)")[![ondrejbouda](https://avatars.githubusercontent.com/u/7202895?v=4)](https://github.com/ondrejbouda "ondrejbouda (1 commits)")[![JaZo](https://avatars.githubusercontent.com/u/3475007?v=4)](https://github.com/JaZo "JaZo (1 commits)")[![atompie](https://avatars.githubusercontent.com/u/16271564?v=4)](https://github.com/atompie "atompie (1 commits)")[![BlackbitDevs](https://avatars.githubusercontent.com/u/8749138?v=4)](https://github.com/BlackbitDevs "BlackbitDevs (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/prewk-xml-string-streamer/health.svg)

```
[![Health](https://phpackages.com/badges/prewk-xml-string-streamer/health.svg)](https://phpackages.com/packages/prewk-xml-string-streamer)
```

###  Alternatives

[karsonzhang/fastadmin-addons

addons package for fastadmin

28183.5k](/packages/karsonzhang-fastadmin-addons)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
