Certainly! The issue arises because when you use UserResource::collection($users)->toArray($request), the resulting array is nested differently compared to a plain Eloquent collection's toArray(). Spatie's ArrayToXml expects a simple associative array, but Laravel API Resources wrap collections in a data key and may include pagination meta.
Example of what you get from a resource collection:
[
'data' => [
['name_data' => '...', 'email_address' => '...'],
// ...
],
'links' => [/* ... */],
'meta' => [/* ... */],
]
This structure causes issues with XML conversion, especially if the root element is not a valid XML tag (e.g., data, links, meta).
How to Fix
Option 1: Pass Only the Data Array
If you only want the user data, extract the data key before passing it to ArrayToXml:
$users = \App\Models\User::paginate(10);
$userResource = \App\Http\Resources\UserResource::collection($users)->toArray(request());
return \Spatie\ArrayToXml\ArrayToXml::convert(
$userResource['data'], // Only the user data array
'users' // Root element name
);
Option 2: Customize the Resource Collection
If you want to include pagination meta, you can restructure the array to have valid XML keys:
$users = \App\Models\User::paginate(10);
$userResource = \App\Http\Resources\UserResource::collection($users)->toArray(request());
$arrayForXml = [
'users' => $userResource['data'],
'pagination' => $userResource['meta'] ?? [],
];
return \Spatie\ArrayToXml\ArrayToXml::convert($arrayForXml, 'response');
Option 3: Use response()->xml() Macro (Optional)
If you want to return XML responses frequently, consider creating a response macro or helper to handle this conversion.
Summary
- Extract the
datakey from the resource collection before passing to ArrayToXml. - Optionally include pagination/meta info under valid XML keys.
- Always specify a valid root element in ArrayToXml.
Example Controller Method:
use App\Models\User;
use App\Http\Resources\UserResource;
use Spatie\ArrayToXml\ArrayToXml;
public function index(Request $request)
{
$users = User::paginate(10);
$userResource = UserResource::collection($users)->toArray($request);
return ArrayToXml::convert(
$userResource['data'],
'users'
);
}
This will output valid XML for your API resource collection.