Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom xml tags to sitemap.xml using mvcsitemapprovider?

Based on what Google defines in Video sitemaps , There are some xml tags should be added to sitemaps for videos, and it should be like this:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
 <loc>http://www.example.com/videos/some_video_landing_page.html</loc>
 <video:video>
   <video:thumbnail_loc>http://www.example.com/thumbs/123.jpg</video:thumbnail_loc>
   <video:title>Grilling steaks for summer</video:title>
   <video:description>Alkis shows you how to get perfectly done steaks every
     time</video:description>
   <video:content_loc>http://www.example.com/video123.mp4</video:content_loc>
   <video:player_loc autoplay="ap=1">
     http://www.example.com/videoplayer.mp4?video=123</video:player_loc>
   <video:duration>600</video:duration>
   <video:expiration_date>2009-11-05T19:20:30+08:00</video:expiration_date>
   <video:rating>4.2</video:rating>
   <video:view_count>12345</video:view_count>
   <video:publication_date>2007-11-05T19:20:30+08:00</video:publication_date>
   <video:family_friendly>yes</video:family_friendly>
   <video:restriction relationship="allow">IE GB US CA</video:restriction>
   <video:gallery_loc title="Cooking Videos">http://cooking.example.com</video:gallery_loc>
   <video:price currency="EUR">1.99</video:price>
   <video:requires_subscription>yes</video:requires_subscription>
   <video:uploader info="http://www.example.com/users/grillymcgrillerson">GrillyMcGrillerson
     </video:uploader>
   <video:live>no</video:live>
 </video:video>

I would like to know how is it possible to add these custom tags dynamically to my sitemap.xml?I am using mvcsitemapprovider

like image 366
Arya Aghaei Avatar asked Jul 24 '17 12:07

Arya Aghaei


2 Answers

well, I could not use the mvcsitemapprovider to achieve my goal yet, but I made this temporary solution and I am trying to make nuget package from it or add it as a feature to the mvcsitemapprovider package, here is the code I added to an ContentResult in a controller and I changed my routeConfig to call this method when the url is look like this "/videoSiteMap.xml" :

public ContentResult VideoSiteMap()
    {
        XmlDocument xmlDoc = new XmlDocument();
        using (XmlWriter writer = xmlDoc.CreateNavigator().AppendChild())
        {
            //writer.Formatting = Formatting.Indented;
            writer.WriteStartDocument();
            writer.WriteStartElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");

            // add namespaces
            writer.WriteAttributeString("xmlns", "video", null, "http://www.google.com/schemas/sitemap-video/1.1");
            List<VideoSiteMap> siteMapp = null;
            siteMapp = ServiceHelper.GetGoogleSiteMap();//I invoked a service
            //you can use a fake loop instead: for (int i = 0; i < 10; i++)
            foreach( var content in siteMapp)
            {
                writer.WriteStartElement("url");

                // required
                writer.WriteElementString("loc", "http://example.com/myplayer.aspx");
                writer.WriteStartElement("video", "video", null);

                // start:optional
                writer.WriteElementString("video", "thumbnail_loc", null, "http://www.example.com/thumbs/123.jpg");
                writer.WriteElementString("video", "title", null, "");
                writer.WriteElementString("video", "description", null, "Alkis shows you how to get perfectly done steaks every time");
                writer.WriteElementString("video", "content_loc", null, "http://www.example.com/video123.mp4");

                writer.WriteStartElement("video", "player_loc", null);
                writer.WriteAttributeString("autoplay", "ap=1");
                writer.WriteString("http://www.example.com/videoplayer.mp4?video=123");
                writer.WriteEndElement(); // video:player_loc
                                          // end:optional

                writer.WriteElementString("video", "duration", null, "100");
                writer.WriteElementString("video", "expiration_date", null, "2009-11-05T19:20:30+08:00");
                writer.WriteElementString("video", "rating", null, "4.2");
                writer.WriteElementString("video", "view_count", null, "12345");
                writer.WriteElementString("video", "publication_date", null, "2007-11-05T19:20:30+08:00");
                writer.WriteElementString("video", "family_friendly", null, "yes");
                writer.WriteElementString("video", "category", null, "Cooking");

                writer.WriteStartElement("video", "restriction", null);
                writer.WriteAttributeString("relationship", "allow");
                writer.WriteString("IE GB US CA");
                writer.WriteEndElement();

                writer.WriteStartElement("video", "gallery_loc", null);
                writer.WriteAttributeString("title", "Cooking Videos");
                writer.WriteString("http://cooking.example.com");
                writer.WriteEndElement();

                writer.WriteStartElement("video", "price", null);
                writer.WriteAttributeString("currency", "EUR");
                writer.WriteString("1.99");
                writer.WriteEndElement();

                writer.WriteElementString("video", "requires_subscription", null, "yes");

                writer.WriteStartElement("video", "uploader", null);
                writer.WriteAttributeString("info", "http://www.example.com/users/grillymcgrillerson");
                writer.WriteString("GrillyMcGrillerson");
                writer.WriteEndElement();

                writer.WriteElementString("video", "live", null, "No");

                writer.WriteEndElement(); // video:video
                writer.WriteEndElement(); //url
            }

            writer.WriteEndElement(); //urlset 
            writer.WriteEndDocument();
            writer.Close();
        }

        var stringWriter = new StringWriter();
        var xmlTextWriter = XmlWriter.Create(stringWriter);
        xmlDoc.WriteTo(xmlTextWriter);
        xmlTextWriter.Flush();
        return Content(stringWriter.GetStringBuilder().ToString().replace("utf-16","utf-8"), "text/xml", Encoding.UTF8);

    }

I replaced utf-16 with utf-8 while returning my xml data because I could not find an easier way to change XmlWriter's result (by default it always returns a utf-16 format)

I hope it help the others, I will be glad if someone help me to make it a nuget package or something :D

like image 165
Arya Aghaei Avatar answered Jan 03 '23 13:01

Arya Aghaei


since the XML sitemap functionality was not the main purpose of MvcSiteMapProvider but an "extra" feature, it was not made very flexible.

I started working on creating a general purpose way to build (and page) XML sitemaps and support the full spec of Google (including videos). But realized that this should be a completely separate component than MvcSiteMapProvider, and never released it. You are welcome to take what you need from here.

like image 34
NightOwl888 Avatar answered Jan 03 '23 14:01

NightOwl888