Skip to content

#258 - Add XmlStreamReaderTask - #260

Merged
njoubert-cleverage merged 1 commit into
mainfrom
258
Oct 12, 2026
Merged

njoubert-cleverage merged 1 commit into
mainfrom
258

Conversation

@njoubert-cleverage

Copy link
Copy Markdown
Member

Description

Fixes #258.

New iterable task CleverAge\ProcessBundle\Task\File\Xml\XmlStreamReaderTask, reading an XML file element by element with \XMLReader: memory stays constant whatever the file size, unlike XmlReaderTask which loads the whole file in a \DOMDocument (kept unchanged).

  • Options: node_name (string, required): qualified name of the elements to iterate on (e.g. product, g:item); file_path (string|null, default null): when null, the path is read from the input (like JsonStreamReaderTask).
  • Output: each matching element, expanded with \XMLReader::expand() as the root \DOMElement of its own \DOMDocument, so it can be passed directly to XpathEvaluatorTransformer with relative queries (@sku, name/text()). Namespaces declared on ancestors are copied, so prefixed queries (g:price/text()) work.
  • Elements are matched at any depth; the subtree of a matching element is skipped (a nested element with the same name is part of its parent output).
  • No matching element: the task is skipped.
  • The reader is moved in execute() (next() only tells whether the file is still open), so that XML errors are thrown in execute() and handled by the task error_strategy. Invalid XML (including an empty file) throws an \UnexpectedValueException with the libxml messages (line/column), as XmlReaderTask; warnings are tolerated. A missing/unreadable file or no file path throws an \UnexpectedValueException.
  • The file is released at the end of the iteration and on finalize(), so that the task can read it again on its next input.

Requires the xmlreader extension (enabled by default, like dom); it is documented but not added to composer.json require, to avoid changing the requirements in a minor version.

Tests: XmlStreamReaderTaskTest (17 cases, including xpath evaluation through XpathEvaluatorTransformer). PHPStan, PHPUnit (897 tests), PHP-CS-Fixer and Rector pass. Demonstrated by demo.file.xml_stream_reader in process-bundle-demo.

Requirements

  • Documentation updates
    • Reference
    • Cookbooks
    • Changelog
  • Unit tests

Breaking changes

None: new task.

🤖 Generated with Claude Code

… file element by element with \XMLReader (constant memory), outputting each element named node_name as a \DOMElement in its own \DOMDocument, ready for XpathEvaluatorTransformer. Add documentation and tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@njoubert-cleverage
njoubert-cleverage merged commit f9cc91f into main Oct 12, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add an XmlStreamReaderTask to read large XML files element by element

1 participant