Install the Package
composer require a9f/fractor-xml --dev
Ensure you’re using --dev if this is for local development or testing.
Register the Service Provider
Add the package to your config/app.php under providers:
AndreasWolf\FractorXml\FractorXmlServiceProvider::class,
First Use Case: Basic XML Processing
Create a custom rule implementing a9f\FractorXml\Contract\XmlFractor:
use a9f\FractorXml\Contract\XmlFractor;
use DOMNode;
class ExampleXmlRule implements XmlFractor
{
public function process(DOMNode $node): void
{
// Example: Log all element names
error_log($node->nodeName);
}
}
Tag the rule in your service container:
$this->app->tag([ExampleXmlRule::class], ['fractor.xml_rule']);
Run the Processor
Use the XmlFileProcessor to analyze/modify an XML file:
use AndreasWolf\FractorXml\Processor\XmlFileProcessor;
$processor = app(XmlFileProcessor::class);
$processor->process('path/to/file.xml');
Rule-Based Processing
DOMNode methods (childNodes, firstChild, nextSibling) to traverse the XML tree.nodeName, nodeValue, or XPath ($node->xpath()) to target specific nodes.DOMNode methods (e.g., setAttribute, appendChild).Example: Update all <price> tags with a discount:
public function process(DOMNode $node): void
{
if ($node->nodeName === 'price') {
$newValue = $node->nodeValue * 0.9;
$node->nodeValue = number_format($newValue, 2);
}
}
Integration with Laravel
use Illuminate\Console\Command;
use AndreasWolf\FractorXml\Processor\XmlFileProcessor;
class ProcessXmlCommand extends Command
{
protected $signature = 'xml:process {files*}';
protected $description = 'Process XML files with Fractor rules';
public function handle(XmlFileProcessor $processor)
{
foreach ($this->argument('files') as $file) {
$processor->process($file);
}
}
}
HandleUploadedFile events).Batch Processing
Storage facade to iterate over files in a directory:
foreach (Storage::files('xml/') as $file) {
$processor->process(storage_path("app/{$file}"));
}
Validation Rules
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(
['xml' => file_get_contents($file)],
['xml' => 'required|xml']
);
XML Parsing Errors
try {
$processor->process($file);
} catch (\Exception $e) {
Log::error("Failed to process {$file}: " . $e->getMessage());
}
libxml_use_internal_errors(true) to debug parsing issues:
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->load($xmlString);
foreach (libxml_get_errors() as $error) {
error_log($error->message);
}
Performance with Large Files
DOMXPath for targeted queries instead of full traversal.SimpleXML for read-heavy tasks.Namespace Handling
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('ns', 'http://example.com/ns');
$nodes = $xpath->query('//ns:element');
Rule Ordering
register method:
$this->app->bind(XmlFileProcessor::class, function ($app) {
$processor = new XmlFileProcessor();
$processor->setRules([
HighPriorityRule::class,
LowPriorityRule::class,
]);
return $processor;
});
Debugging Nodes
public function process(DOMNode $node): void
{
dump([
'name' => $node->nodeName,
'value' => $node->nodeValue,
'children' => iterator_to_array($node->childNodes),
]);
}
Testing Rules
XmlFileProcessor in tests with mock DOMDocument:
public function testXmlRule()
{
$dom = new DOMDocument();
$dom->loadXML('<root><price>100</price></root>');
$rule = new ExampleXmlRule();
$rule->process($dom->documentElement->firstChild);
$this->assertEquals('90.00', $dom->documentElement->firstChild->nodeValue);
}
Extending Functionality
XmlFileProcessor to add pre/post-processing hooks:
class CustomXmlProcessor extends XmlFileProcessor
{
protected function beforeProcess(string $file): void
{
// Pre-processing logic (e.g., validation)
}
protected function afterProcess(string $file): void
{
// Post-processing logic (e.g., notifications)
}
}
event(new XmlNodeProcessed($node));
Configuration Quirks
config/fractor.php (if available) or manually in the service provider:
$this->app->tag([CustomRule::class], ['fractor.xml_rule']);
Memory Management
DOMDocument::loadXML() with LIBXML_NOBLANKS or LIBXML_NOCDATA flags to reduce memory usage:
$dom->loadXML($xml, LIBXML_NOBLANKS);
How can I help you explore Laravel packages today?