Question

I want to serialize like this

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
</urlset>

But wrong result generated.

My class is here

[Serializable]
[XmlRoot("urlset")]    
public class GoogleSiteMap
{        
    public GoogleSiteMap() {
        xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
        xmlnsNews = "http://www.google.com/schemas/sitemap-news/0.9";
        Urls = new List<gUrlBase>();
    }

    [XmlAttribute]
    public string xmlns { get; set; }

    [XmlAttribute("news",Namespace="xmlns")]
    public string xmlnsNews { get; set; }

    [XmlElement("url")]
    public List<gUrlBase> Urls { get; set; }
}

Serializer is here

public static void GenerateGoogle(GoogleSiteMap smap,string filePath) {

        XmlSerializer ser = new XmlSerializer(typeof(GoogleSiteMap));
        using (FileStream fs = new FileStream(filePath, FileMode.Create))
        {
            ser.Serialize(fs, smap);
            fs.Close();
        }            

    }

Then result is here

<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:d1p1="xmlns" d1p1:news="http://www.google.com/schemas/sitemap-news/0.9"/>

What's wrong on my class declaration?

Another QUESTION 2

How can i declare like this

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
    <url>
        <loc>http://www.example.org/business/article55.html</loc>
        <news:news></news:news>
    </url>
    <url>
        <loc>http://www.example.org/business/page1.html</loc>
        <lastmod>2010-10-10</lastmod>
        <changefreq>weekly</changefreq>
    </url>
</urlset>

my declaration is here

[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
    public class GoogleSiteMap
    {
        public GoogleSiteMap()
        {
            Urls = new List<gUrlBase>();
        }

        //[XmlElement("url")]
        [XmlElement("url",Type = typeof(gNormalUrl))]
        [XmlElement("url",Type = typeof(gNewsUrl))]
        public List<gUrlBase> Urls { get; set; }
    }

This is return error

The XML element 'url' from namespace 'http://www.sitemaps.org/schemas/sitemap/0.9' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.

How can i declare Same root name "url"?

Was it helpful?

Solution

You need to use the right namespace:

[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]

you can take away xmlns and xmlnsNews properties - they do something else. Likewise, any data in ""http://www.google.com/schemas/sitemap-news/0.9" will need to be marked as such. Whether the namespace alias is news is irrelevant (it is only an alias), but that can be controlled via XmlSerializerNamespaces if you like. You do not need [Serializable].

For example, if each <url> needs to be in the "http://www.google.com/schemas/sitemap-news/0.9" namespace, and you want to use "http://www.sitemaps.org/schemas/sitemap/0.9" as the overall namespace and "http://www.google.com/schemas/sitemap-news/0.9" aliased as "news", then:

static class Program
{
    static void Main()
    {
        var ns = new XmlSerializerNamespaces();
        ns.Add("", "http://www.sitemaps.org/schemas/sitemap/0.9");
        ns.Add("news", "http://www.google.com/schemas/sitemap-news/0.9");
        var ser = new XmlSerializer(typeof (GoogleSiteMap));
        var obj = new GoogleSiteMap {Urls = new List<string> {"abc", "def", "ghi"}};
        ser.Serialize(Console.Out, obj, ns);
    }
}

[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleSiteMap
{

    [XmlElement("url", Namespace = "http://www.google.com/schemas/sitemap-news/0.9")]
    public List<string> Urls { get; set; }
}

This generates:

<urlset
     xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
     xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <news:url>abc</news:url>
  <news:url>def</news:url>
  <news:url>ghi</news:url>
</urlset>

(I haven't checked what the actual content namespaces are - this is just to show the relationship between namespaces in the data, namespaces in the xml, and namespace-aliases)


Re your edit - something like:

static class Program
{
    static void Main()
    {
        var ns = new XmlSerializerNamespaces();
        ns.Add("", "http://www.sitemaps.org/schemas/sitemap/0.9");
        ns.Add("news", "http://www.google.com/schemas/sitemap-news/0.9");
        var ser = new XmlSerializer(typeof (GoogleSiteMap));
        var obj = new GoogleSiteMap {Urls = {
            new SiteUrl { Location = "http://www.example.org/business/article55.html", News = ""},
            new SiteUrl { Location = "http://www.example.org/business/page1.html", LastModified = new DateTime(2010,10,10),
            ChangeFrequency = "weekly"}
        }};
        ser.Serialize(Console.Out, obj, ns);
    }
}

[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleSiteMap
{
    private readonly List<SiteUrl> urls = new List<SiteUrl>();
    [XmlElement("url")]
    public List<SiteUrl> Urls { get { return urls; } }
}

public class SiteUrl
{
    [XmlElement("loc")]
    public string Location { get; set; }
    [XmlElement("news", Namespace = "http://www.google.com/schemas/sitemap-news/0.9")]
    public string News { get; set; }
    [XmlElement("lastmod")]
    public DateTime? LastModified { get; set; }
    [XmlElement("changefreq")]
    public string ChangeFrequency { get; set; }

    public bool ShouldSerializeLastModified() { return LastModified.HasValue; }
}

which generates:

<urlset xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://www.example.org/business/article55.html</loc>
    <news:news />
  </url>
  <url>
    <loc>http://www.example.org/business/page1.html</loc>
    <lastmod>2010-10-10T00:00:00</lastmod>
    <changefreq>weekly</changefreq>
  </url>
</urlset>

OTHER TIPS

Please use below full code that made by me

Please see below full code

#region GoogleNewsSiteMap Class
[XmlRoot("urlset", Namespace = "http://www.sitemaps.org/schemas/sitemap/0.9")]
public class GoogleNewsSiteMap
{
    const string _newsSiteMapSchema = "http://www.google.com/schemas/sitemap-news/0.9";
    const string _newsSiteMapPrefix = "n";

    public void Create(string loc, string prioity, string language, string name, string genres, string publicationDate, string title)
    {
        NewsSiteMap news = new NewsSiteMap();
        news.Loc = loc;
        news.Priority = prioity;
        news.NewsSiteMapNews.Publication.Language = language;
        news.NewsSiteMapNews.Publication.Name = name;
        news.NewsSiteMapNews.Genres = genres;
        news.NewsSiteMapNews.PublicationDate = publicationDate;
        news.NewsSiteMapNews.Title = title;
        List.Add(news);
    }

    public string GetXMLString()
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        settings.IndentChars = ("    ");
        settings.Encoding = new UTF8Encoding(false);
        using (StringWriter str = new StringWriter())
        using (XmlWriter writer = XmlWriter.Create(str, settings))
        {
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add(_newsSiteMapPrefix, _newsSiteMapSchema);
            XmlSerializer xser = new XmlSerializer(typeof(GoogleNewsSiteMap));
            xser.Serialize(writer, this, ns);
            return str.ToString();
        }
    }

    private List<NewsSiteMap> _list = null;
    [XmlElement("url")]
    public List<NewsSiteMap> List
    {
        get
        {
            if (_list == null)
            {
                _list = new List<NewsSiteMap>();
            }
            return _list;
        }
    }

    #region NewsSiteMap Class
    public class NewsSiteMap
    {
        private string _loc = string.Empty;
        private string _priority = string.Empty;
        private NewsSiteMap_News _newsSiteMap_News = null;

        [XmlElement("loc")]
        public string Loc
        {
            get { return _loc; } set { _loc = value; }
        }

        [XmlElement("priority")]
        public string Priority
        {
            get { return _priority; }  set { _priority = value; }
        }

        [XmlElement("news", Namespace = _newsSiteMapSchema)]
        public NewsSiteMap_News NewsSiteMapNews
        {
            get {
                if (_newsSiteMap_News == null)
                {
                    _newsSiteMap_News = new NewsSiteMap_News();
                }
                return _newsSiteMap_News; 
            }
            set { _newsSiteMap_News = value; }
        }

        #region NewsSiteMap_News Class
        public class NewsSiteMap_News
        {
            private NewsSiteMap_Publication _publication = null;
            private string _genres = string.Empty;
            private string _publicationDate = string.Empty;
            private string _title = string.Empty;
            private string _keywords = string.Empty;
            private string _stockTickers = string.Empty;

            [XmlElement("publication", Namespace = _newsSiteMapSchema)]
            public NewsSiteMap_Publication Publication
            {
                get
                {
                    if (_publication == null)
                    {
                        _publication = new NewsSiteMap_Publication();
                    }
                    return _publication;
                }
                set { _publication = value; }
            }

            [XmlElement("genres")]
            public string Genres
            {
                get { return _genres; }
                set { _genres = value; }
            }

            [XmlElement("publication_date")]
            public string PublicationDate
            {
                get
                {
                    try
                    {
                        return string.Format("{0:s}", Convert.ToDateTime(_publicationDate)) + string.Format("{0:zzz}", Convert.ToDateTime(_publicationDate));
                    }
                    catch (Exception ex)
                    {
                        return _publicationDate;
                    }
                }
                set { _publicationDate = value; }
            }

            public string Title
            {
                set { _title = value; }
            }

            [XmlElement("title")]
            public XmlCDataSection CTitle
            {
                get
                {
                    XmlDocument doc = new XmlDocument();
                    return doc.CreateCDataSection(_title);
                }
                set { _title = value.Value; }
            }

            [XmlElement("keywords")]
            public string Keywords
            {
                get { return _keywords; }  set { _keywords = value; }
            }

            [XmlElement("stock_tickers")]
            public string StockTickers
            {
                get { return _stockTickers; }  set { _stockTickers = value; }
            }

            #region NewsSiteMap_Publication Class
            public class NewsSiteMap_Publication
            {
                private string _name = string.Empty;
                private string _language = string.Empty;

                [XmlElement("name")]
                public string Name
                {
                    get { return _name; }
                    set { _name = value; }
                }

                [XmlElement("language")]
                public string Language
                {
                    get { return _language; }
                    set { _language = value; }
                }
            }
            #endregion NewsSiteMap_Publication Class
        }
        #endregion NewsSiteMap_News Class
    }
    #endregion NewsSiteMap Class
}
#endregion GoogleNewsSiteMap Class

Usage

Response.Clear();
Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
GoogleNewsSiteMap googleNewsSiteMap = new GoogleNewsSiteMap();
googleNewsSiteMap.Create(/*put ur data*/);
Response.Write(googleNewsSiteMap.GetXMLString());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top