Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Xml Laravel Package

sabre/xml

sabre/xml is a lightweight, specialized XML reader and writer for PHP. It makes it easy to parse XML into structured data and generate XML output with namespace support. Version 3 adds strict type declarations and supports PHP 7.4+ and PHP 8.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require sabre/xml
    

    Target v4.x for PHP 8+ or v3.x for PHP 7.4+ with type safety.

  2. First Use Case: Parse a simple XML string into a PHP array:

    use Sabre\Xml\Reader;
    use Sabre\Xml\Service;
    
    $xml = '<root><item>value</item></root>';
    $reader = new Reader();
    $service = new Service();
    $result = $service->parse($reader->parse($xml));
    // Returns: ['root' => ['item' => 'value']]
    
  3. Where to Look First:

    • Reading XML for parsing workflows.
    • Writing XML for serialization patterns.
    • Sabre\Xml\Service (core class) and Sabre\Xml\Writer for output.

Implementation Patterns

Core Workflows

1. Parsing XML into PHP Structures

  • Simple Arrays:
    $service = new Service();
    $data = $service->parse($reader->parse('<root><key>value</key></root>'));
    // ['root' => ['key' => 'value']]
    
  • Typed Objects: Use deserialize() with custom mappings:
    $service->deserialize($reader->parse($xml), MyModel::class);
    
  • Namespaced XML (e.g., SOAP):
    $reader->setNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
    $service->parse($reader->parse($soapXml));
    

2. Writing XML from PHP

  • Basic XML:
    $writer = new Writer();
    $writer->write(['root' => ['item' => 'value']]);
    // Outputs: <root><item>value</item></root>
    
  • Custom Formatting:
    $writer->setIndent(2);
    $writer->write($data);
    
  • Namespaced Output:
    $writer->setNamespace('ns', 'http://example.com/ns');
    $writer->write(['ns:root' => ['ns:item' => 'value']]);
    

3. Integration with Laravel

  • Service Provider:

    // app/Providers/XmlServiceProvider.php
    public function register()
    {
        $this->app->singleton(Service::class, function () {
            return new Service();
        });
    }
    
  • API Responses:

    return response()->xml($data)->header('Content-Type', 'application/xml');
    

    (Use a facade or helper for response()->xml().)

  • Background Jobs:

    ParseXmlJob::dispatch($xmlFilePath)
        ->onQueue('xml-processing');
    

4. Advanced Patterns

  • Custom Deserializers:
    $service->addDeserializer('date', function ($value) {
        return new DateTime($value);
    });
    
  • Streaming Large Files:
    $reader = new Reader();
    $reader->open($largeXmlFilePath);
    while ($reader->read()) {
        $service->parse($reader->getCurrentElement());
    }
    

Gotchas and Tips

Pitfalls

  1. Resource Handling:

    • Closed resources (e.g., after fclose()) will throw exceptions. Reopen or use streams:
      $reader->open($filePath); // Instead of passing a closed resource.
      
    • Fix: Check for is_resource($handle) before parsing.
  2. Namespace Conflicts:

    • Foreign namespaces in values may cause silent failures. Explicitly declare namespaces:
      $reader->setNamespace('ns', 'http://example.com/ns');
      
  3. Empty XML Elements:

    • Infinite loops can occur with malformed XML (e.g., <tag></tag>). Use trimWhitespace:
      $reader->setTrimWhitespace(true);
      
  4. Type Mismatches (v3+):

    • Extending classes requires type declarations. Example:
      class CustomService extends Service {
          public function customParse(array $data): array { ... }
      }
      
  5. PHP 8+ Deprecations:

    • Avoid xml_parse_into_struct() (deprecated). Use Sabre\Xml\Reader instead.

Debugging Tips

  • Enable XML Errors:
    libxml_use_internal_errors(true);
    $reader->parse($xml);
    $errors = libxml_get_errors();
    
  • Validate XML: Use libxml_get_last_error() to catch parsing issues early.

Extension Points

  1. Custom Writers: Extend Sabre\Xml\Writer to add domain-specific formatting:

    class ApiWriter extends Writer {
        public function writeArray(array $data, string $root = 'response') {
            $this->startElement($root);
            foreach ($data as $key => $value) {
                $this->writeElement($key, $value);
            }
            $this->endElement();
        }
    }
    
  2. Deserializer Hooks: Override Service::deserialize() to inject logic:

    $service->addDeserializer('callback', function ($value, $name) {
        return call_user_func($value, $name);
    });
    
  3. Event Listeners: Use Sabre\Xml\Reader::onRead() to intercept parsing:

    $reader->onRead(function ($element) {
        if ($element['name'] === 'secret') {
            $element['value'] = '****';
        }
    });
    

Performance Quirks

  • Memory Usage: For large XML files, use Reader::read() in a loop instead of parse() to avoid loading the entire file into memory.
  • Namespaces: Excessive namespace declarations slow parsing. Group related namespaces:
    $reader->setNamespaces([
        'ns1' => 'http://example.com/ns1',
        'ns2' => 'http://example.com/ns2',
    ]);
    

Laravel-Specific Tips

  1. Caching Parsed XML:

    $cacheKey = 'xml_' . md5($xml);
    $data = Cache::remember($cacheKey, 3600, function () use ($xml) {
        return $service->parse($reader->parse($xml));
    });
    
  2. Form Request Validation:

    public function rules()
    {
        return [
            'xml_data' => 'required|xml', // Custom validator for XML structure.
        ];
    }
    
  3. Artisan Commands:

    class ParseXmlCommand extends Command {
        protected $service;
    
        public function __construct(Service $service) {
            parent::__construct();
            $this->service = $service;
        }
    
        public function handle() {
            $xml = file_get_contents($this->argument('file'));
            $data = $this->service->parse($reader->parse($xml));
            // Process $data...
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport