Creating XML sitemap

I’m trying to create an xml for sitemap but i get a plain text not xml format

my controller is

    public function actionIndex()
        {
    		$channels = Channel::find()->all(); 

    		\Yii::$app->response->format = \yii\web\Response::FORMAT_XML;

    		return $this->renderPartial('/sitemap/_viewChannel', [
    			'channels'	 => $channels,
    		]);
        }

My view is

    <?php
             use yii\helpers\Html;
            use yii\helpers\Url;

    header("Content-Type: application/xml; charset=utf-8");

    echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;

    ?>


    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

    	<?php foreach ($channels as $channel){ ?>
    		<url>
    			<loc><?=Url::to(['/chn-channel/view', 't'=>$channel->channel_uid])?></loc>
    			<changefreq>daily</changefreq>
    		</url>
    	<?php } ?>
    	
    </urlset>

1 Like

You should read this article https://www.yiiframework.com/doc/guide/2.0/en/runtime-responses

  1. Don’t use header function - instead use $response->format. If you want to set in the header some params, use
    $headers = Yii::$app->response->headers;
    $headers->add(‘Pragma’, ‘no-cache’);
  2. Don’t set <?xml version="1.0" encoding="UTF-8"?>. You set response format - it’s enough.

I changed my controller and view as you said

this is my controller

public function actionIndex()
    {
	$channels = Channel::find()->all(); 
			
	$response = Yii::$app->response;
	$response->format = \yii\web\Response::FORMAT_XML;
	
	$headers = Yii::$app->response->headers;
	$headers->add('Content-Type', 'application/xml');

	return $this->renderPartial('/sitemap/_viewChannel', [
		'channels'	 => $channels,
	]);
}

and my view is

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">

	<?php foreach ($channels as $channel){ ?>
		<url>
			<loc><?=Url::to(['/chn-channel/view', 't'=>$channel->channel_uid])?></loc>
			<changefreq>daily</changefreq>
		</url>
	<?php } ?>
	
</urlset>

but not big change

I guess you can try FORMAT_RAW instead of FORMAT_XML.

FORMAT_XML uses yii\web\XmlResponseFormatter which expects the input data to be a PHP array.

public function actionInfo()
{
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return [
        'message' => 'hello world',
        'code' => 100,
    ];
}

This is from the guide (https://www.yiiframework.com/doc/guide/2.0/en/runtime-responses#response-body)
Note that an array is returned here. It is for FORMAT_JSON, but I believe that it is the same for FORMAT_XML.

Since you are writing a xml manually in the view, I think you should use FORMAT_RAW.

[edit]
Moreover, because XML attribute is not supported in XmlResponseFormatter, you can not use it.

YES, Worked

solution
Changing :

$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_XML;

$headers = Yii::$app->response->headers;
$headers->add('Content-Type', 'application/xml');

to

Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
Yii::$app->response->headers->add('Content-Type', 'text/xml');
1 Like

I think that the extra whitespace/linefeeds before your root element may have been a problem too.