如何在c#中使用XmlSerializer序列化google站点地图

本文关键字:序列化 XmlSerializer google 站点 地图 | 更新日期: 2023-09-27 18:11:13

我想这样序列化

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

但是产生错误的结果。

我的班级在这里

[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; }
}

序列化器在这里

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"/>

我的类声明有什么问题?

另一个问题2

如何这样声明

<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>

我的声明在这里

[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; }
    }

返回错误

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.

我如何声明相同的根名称"url"?

如何在c#中使用XmlSerializer序列化google站点地图

您需要使用正确的命名空间:

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

你可以去掉xmlnsxmlnsNews的性质它们做别的事情。同样,"http://www.google.com/schemas/sitemap-news/0.9"中的任何数据都需要这样标记。名称空间别名是否为news无关紧要(它只是一个别名),但是如果您愿意,可以通过XmlSerializerNamespaces来控制。你不需要[Serializable] .

例如,如果每个<url>需要在"http://www.google.com/schemas/sitemap-news/0.9"命名空间中,并且您希望使用"http://www.sitemaps.org/schemas/sitemap/0.9"作为整体命名空间,并将"http://www.google.com/schemas/sitemap-news/0.9"别名为"news",则:

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; }
}
由此产生

:

<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>

(我没有检查实际的内容名称空间是什么—这只是为了显示数据中的名称空间、xml中的名称空间和名称空间别名之间的关系)


重新编辑-类似于:

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; }
}

生成:

<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>

请使用下面由我制作的完整代码

请参阅下面的完整代码

#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
使用

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());