Skip to main content
This guide walks you through the fundamental features of Laravel XML using a practical example: managing notes in XML format.

Import XML data

Let’s start by importing an XML file containing notes. Create a file called notes.xml:
<notes count="2">
    <note completed="true">
        <to>John</to>
        <from>Jane</from>
        <heading>Meeting</heading>
        <body>Don't forget about our meeting tomorrow!</body>
        <completed_at>01-01-2024 12:00</completed_at>
    </note>
    <note completed="false">
        <to>Sarah</to>
        <from>Mike</from>
        <heading>Project Update</heading>
        <body>Please review the latest changes.</body>
        <completed_at/>
    </note>
</notes>
Import this file using the XML facade:
use XML;

$notes = XML::import('notes.xml')->get();

// Access elements
echo $notes->note[0]->to; // "John"
echo $notes->note[1]->heading; // "Project Update"

// Access attributes
echo $notes->note[0]->attribute('completed'); // "true"

Cast to Eloquent models

One of Laravel XML’s most powerful features is automatic casting to Eloquent models. Define a Note model:
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Note extends Model
{
    protected $fillable = [
        'to',
        'from',
        'heading',
        'body',
        'completed_at',
    ];

    protected $casts = [
        'completed_at' => 'datetime',
    ];
}
Now cast XML elements directly to Note model instances:
use App\Models\Note;
use XML;

$data = XML::import('notes.xml')
    ->cast('note')->to(Note::class)
    ->get();

// Each note is now a Note model instance
foreach ($data->note as $note) {
    echo $note->to; // Access as model properties
    echo $note->completed_at->format('Y-m-d'); // Use Laravel's date casting
}
The cast() method works with arrays of elements automatically. If note contains multiple items, each one will be cast to a Note instance.

Transform XML data

Transformers let you modify XML data before using it. The built-in array transformer ensures an element is always an array:
$data = XML::import('notes.xml')
    ->expect('note')->as('array')
    ->get();

// $data->note is now always an array, even if XML contains a single note
foreach ($data->note as $note) {
    // Process notes
}
Create custom transformers for advanced filtering. This example filters only completed notes:
use Flowgistics\XML\Transformers\Transformer;
use Flowgistics\XML\Data\XMLElement;

class CompletedNotesFilter implements Transformer
{
    public static function apply($data)
    {
        return array_filter($data, function ($note) {
            return $note->attribute('completed') === 'true';
        });
    }
}
Apply your custom transformer:
$completedNotes = XML::import('notes.xml')
    ->transform('note')->with(CompletedNotesFilter::class)
    ->get();

// $completedNotes->note now contains only notes with completed="true"

Optimize key names

XML element names often use different casing than your application. Use the optimize() method to convert keys:
// Convert to snake_case
$data = XML::import('notes.xml')
    ->optimize('underscore')
    ->get();

// Convert to camelCase
$data = XML::import('notes.xml')
    ->optimize('camelcase')
    ->get();

echo $data->note[0]->completedAt; // Converted from completed_at
This is particularly useful when importing XML from external APIs that don’t follow Laravel naming conventions.

Export data to XML

Export PHP arrays to XML format using the export() method:
use XML;

$data = [
    'note' => [
        [
            'to' => 'John',
            'from' => 'Jane',
            'heading' => 'Reminder',
            'body' => 'Call the client tomorrow',
        ],
        [
            'to' => 'Sarah',
            'from' => 'Mike',
            'heading' => 'Follow-up',
            'body' => 'Send the proposal',
        ],
    ],
];

$xml = XML::export($data)
    ->rootTag('notes')
    ->version('1.0')
    ->encoding('UTF-8')
    ->toString();

echo $xml;
Output:
<?xml version="1.0" encoding="UTF-8"?>
<notes>
    <note>
        <to>John</to>
        <from>Jane</from>
        <heading>Reminder</heading>
        <body>Call the client tomorrow</body>
    </note>
    <note>
        <to>Sarah</to>
        <from>Mike</from>
        <heading>Follow-up</heading>
        <body>Send the proposal</body>
    </note>
</notes>

Save exported XML to file

Save the generated XML directly to a file:
XML::export($data)
    ->rootTag('notes')
    ->toFile('output.xml');
For pretty-printed output with indentation:
XML::export($data)
    ->rootTag('notes')
    ->usePrettyOutput()
    ->toFile('output.xml');

Complete example

Here’s a complete example that imports notes, filters completed ones, casts them to models, and exports them:
use App\Models\Note;
use Flowgistics\XML\Transformers\Transformer;
use XML;

// Custom transformer
class CompletedNotesFilter implements Transformer
{
    public static function apply($data)
    {
        return array_filter($data, function ($note) {
            return $note->attribute('completed') === 'true';
        });
    }
}

// Import and process
$data = XML::import('notes.xml')
    ->transform('note')->with(CompletedNotesFilter::class)
    ->expect('note')->as('array')
    ->cast('note')->to(Note::class)
    ->optimize('camelcase')
    ->get();

// Work with models
foreach ($data->note as $note) {
    echo "Task for {$note->to}: {$note->heading}\n";
}

// Export back to XML
$exportData = array_map(fn($note) => [
    'to' => $note->to,
    'from' => $note->from,
    'heading' => $note->heading,
    'body' => $note->body,
], $data->note);

XML::export(['note' => $exportData])
    ->rootTag('completed_notes')
    ->usePrettyOutput()
    ->toFile('completed.xml');

Next steps

Now that you understand the basics, explore advanced features:

Importing

Learn about raw imports, remote URLs, and advanced parsing options

Exporting

Discover view exports, custom root tags, and export configuration

Casting

Master custom casts and the Castable interface for complex objects

Transforming

Create advanced transformers for complex data manipulation

Build docs developers (and LLMs) love