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

veewee/xml

Type-safe, declarative XML toolkit for PHP. Work with DOM safely, encode/decode XML like JSON, handle errors, and stream large files with memory-safe reader/writer. Includes XSD schema tools and XSLT transformations. Spec-compliant from v4 (PHP 8.4+).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require veewee/xml
    

    Ensure PHP 8.4+ for full spec compliance (or use v3.x for older PHP versions).

  2. First Use Case: Generate a simple XML file:

    use VeeWee\Xml\Writer\Writer;
    use function VeeWee\Xml\Writer\Builder\document;
    use function VeeWee\Xml\Writer\Builder\element;
    use function VeeWee\Xml\Writer\Builder\value;
    
    $writer = Writer::forFile('output.xml');
    $writer->write(
        document('1.0', 'UTF-8',
            element('root', value('Hello, XML!'))
        )
    );
    

    Output: output.xml with <root>Hello, XML!</root>.

  3. Key Entry Points:

    • Writer: Core class for XML generation (Writer::forFile(), Writer::inMemory()).
    • Builders: Declarative functions like element(), attribute(), children().
    • Configurators: Formatting options like indentation().

Implementation Patterns

1. Declarative XML Generation

Pattern: Use builders to construct XML hierarchically.

$xml = element('user',
    attribute('id', 123),
    children([
        element('name', value('John Doe')),
        element('email', value('john@example.com')),
    ])
);
Writer::inMemory()->write($xml)->map(memory_output());

When to Use: For structured data (e.g., API responses, config files).

2. Memory-Safe Large XML

Pattern: Stream data using generators or iterables.

function generateItems(): Generator {
    foreach (DB::query('SELECT * FROM items') as $item) {
        yield element('item', value($item['name']));
    }
}
Writer::forFile('large.xml')->write(
    element('items', children(generateItems()))
);

When to Use: Processing large datasets (e.g., CSV-to-XML conversion).

3. Namespaces and Prefixes

Pattern: Centralize namespace declarations.

$xml = element('catalog',
    namespace_attribute('http://example.com/ns', 'ex'),
    children([
        prefixed_element('ex', 'product', value('Widget')),
    ])
);

When to Use: Working with SOAP, XSD, or domain-specific XML schemas.

4. Encoding/Decoding

Pattern: Treat XML like JSON for serialization.

$xmlString = xml_encode(['user' => ['name' => 'Alice']]);
$data = xml_decode($xmlString);

When to Use: Quick serialization/deserialization (e.g., caching, config).

5. DOM Manipulation

Pattern: Query and modify XML using DOM methods.

$dom = new \VeeWee\Xml\Dom\Dom('input.xml');
$nodes = $dom->query('//user[name="John"]');
foreach ($nodes as $node) {
    $node->setAttribute('active', 'true');
}
$dom->save('output.xml');

When to Use: Parsing/transforming existing XML (e.g., XSLT-like operations).

6. Error Handling

Pattern: Wrap XML operations in try-catch.

try {
    $writer = Writer::forFile('invalid.xml');
    $writer->write(element('root', value('<?malformed'))); // Throws on write
} catch (\VeeWee\Xml\Exception\XmlException $e) {
    log::error($e->getMessage());
}

When to Use: User-uploaded XML or untrusted sources.


Gotchas and Tips

Pitfalls

  1. Raw XML Injection:

    • Issue: raw() bypasses escaping. Malicious input can break XML or inject scripts.
    • Fix: Sanitize input or use value() for user-provided data.
      // UNSAFE
      raw($_GET['input']);
      
      // SAFE
      value(htmlspecialchars($_GET['input']));
      
  2. Namespace Collisions:

    • Issue: Prefixes must match declared namespaces. Mismatches cause silent failures.
    • Fix: Use namespace_attribute() before prefixed_* builders.
      // WRONG (missing xmlns)
      prefixed_attribute('ns', 'attr', 'value');
      
      // CORRECT
      element('root',
          namespace_attribute('http://ns.com', 'ns'),
          prefixed_attribute('ns', 'attr', 'value')
      );
      
  3. Memory Leaks with inMemory():

    • Issue: Large XML in memory can exhaust resources.
    • Fix: Use Writer::forStream() with a temporary file or database BLOB.
  4. PHP 8.4+ Spec Compliance:

    • Issue: v4+ enforces stricter DOM behavior (e.g., case-sensitive tags).
    • Fix: Test with libxml_use_internal_errors(true) if migrating from v3.
      libxml_use_internal_errors(true);
      $dom = new \VeeWee\Xml\Dom\Dom('file.xml');
      
  5. Encoding Mismatches:

    • Issue: xml_encode()/xml_decode() default to UTF-8. Non-UTF-8 data may corrupt.
    • Fix: Explicitly set encoding:
      $xml = xml_encode(['data' => '€'], 'ISO-8859-1');
      

Debugging Tips

  1. Validate XML: Use libxml_get_errors() to debug malformed XML:

    libxml_use_internal_errors(true);
    $dom = new \VeeWee\Xml\Dom\Dom('file.xml');
    foreach (libxml_get_errors() as $error) {
        error_log($error->message);
    }
    
  2. Inspect Builders: Convert builders to XML strings for debugging:

    $xmlString = Writer::inMemory()
        ->write($yourBuilder)
        ->map(memory_output());
    dd($xmlString);
    
  3. XSD Validation: Validate against schemas:

    $validator = new \VeeWee\Xml\Xsd\Validator('schema.xsd');
    $isValid = $validator->validate('data.xml');
    

Extension Points

  1. Custom Builders: Extend functionality by implementing the Builder interface:

    class CustomTag implements \VeeWee\Xml\Writer\Builder\Builder {
        public function __invoke(XMLWriter $writer): Generator {
            yield $writer->startElement('custom');
            yield $writer->text('dynamic content');
            yield $writer->endElement();
        }
    }
    

    Use with children([new CustomTag()]).

  2. Configurators: Add global settings (e.g., auto-indentation):

    Writer::configure(
        \VeeWee\Xml\Writer\Configurator\indentation('    ')
    );
    
  3. Mappers: Convert XML to other formats (e.g., JSON):

    $mapper = new class implements \VeeWee\Xml\Writer\Mapper\Mapper {
        public function __invoke(string $xml): array {
            return json_decode(xml_decode($xml), true);
        }
    };
    Writer::inMemory()->write($xml)->map($mapper);
    

Performance Tips

  1. Reuse Writers: Instantiate Writer once and reuse for multiple writes (e.g., in a loop).

    $writer = Writer::forFile('output.xml');
    foreach ($items as $item) {
        $writer->write(element('item', value($item)));
    }
    
  2. Disable Output Buffering: For large files, disable PHP buffering:

    Writer::forFile('large.xml', \VeeWee\Xml\Writer\Configurator\output_buffering(false));
    
  3. Lazy Loading: Use generators for nested elements to defer processing:

    function lazyChildren(): Generator {
        foreach (fetchData() as $data) {
            yield element('child', value($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