Flo Schild
Flo Schild

Reputation: 5294

twig - render xml content with loops (even empty content)

I am building a web service that render content in multiple formats, basically json, xml and html (for testing only, no worry about it).

The JSON and HTML renderings work fine, I have just added a "toArray()" method in my entities in order to render it. (I guess/hope it is the best/only way, for JSON exporting at least ?!)

But I have got some troubles about the XML rendering. (I apologize, but I hate that language, and usually never use it for data exporting, but it is seems to be a requirement for this project.) I call a view, named for instance, MyBundle:MyController:myView.xml.twig, and got an error that I cannot fix...

This page contains the following errors:

error on line 2 at column 1: Extra content at the end of the document

Below is a rendering of the page up to the first error.

I searched about it on Google and it seems to be an usual XML parsing error, but I do not know what is the cause !

A few code lines for more informations...

My routing.yml router file :

# Prefixed by /api
# The final route will looks like /api/bookings.{_format}
my_bundle_bookingpage:
    pattern:  /bookings.{_format}
    defaults: { _controller: MyBundle:Bookings:index, _format: json }
    requirements:
        _format: json|xml|html
        _method: 'get'

My BookingsController.php :

<?php

namespace My\Bundle\Controller;

class BookingsController extends RestController
{
    public function indexAction()
    {
        $request = $this->getRequest();
        $em = $this->getDoctrine()->getEntityManager();

        $bookings = $em->getRepository('MyCoreBundle:Booking')->findAll();

        $parameters = array(
            'bookings' => $bookings
        );

        switch ($request->get('_format')) {
            case 'html':
            case 'xml':
                return $this->render('MyBundle:Bookings:index.'.$request->get('_format').'.twig', $parameters);
                break;
            default:
                foreach ($parameters['bookings'] as &$booking) {
                    $booking = $booking->toArray();
                }
                return $this->generateJsonResponse($parameters, 200);
                break;
        }
    }
}

And the RestController, that just provides a simple JsonResponse method :

<?php

namespace My\Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;

class RestController extends Controller
{
    public function generateJsonResponse($content = array(), $status = 200)
    {
        $response = new JsonResponse($content, $status);

        return $response;
    }
}

And finally, myView.xml :

<bookings>
    {% for booking in bookings %}
        <booking>
            <id>{{ booking.id }}</id>
            <created>{{ booking.createdAt }}</created>
            <updated>{{ booking.updatedAt }}</updated>
            <name>{{ booking.name }}</name>
            <date>{{ booking.datetime }}</date>
            <notes>{{ booking.notes }}</notes>
            <persons>{{ booking.persons }}</persons>
        </booking>
    {% endfor %}
</bookings>

Upvotes: 0

Views: 1423

Answers (1)

Emii Khaos
Emii Khaos

Reputation: 10085

Take a look at the FOSRestBundle in combination with the JMSSerializerBundle

Upvotes: 2

Related Questions