如何使用 XmlSerializer 在 C# 中序列化 google sitemap

发布于 2024-12-09 21:46:17 字数 2623 浏览 1 评论 0原文

我想像这样序列化

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

    }

然后结果在这里

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

这是返回错误

< code>命名空间“http://www.sitemaps.org/schemas/sitemap/0.9”中的 XML 元素“url”已存在于当前范围中。使用 XML 属性为元素指定另一个 XML 名称或命名空间。

如何声明相同的根名称“url”?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷情妓 2024-12-16 21:46:17

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

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

您可以删除 xmlnsxmlnsNews 属性 - 它们会执行其他操作。同样,“”http://www.google.com/schemas/sitemap- 中的任何数据news/0.9”需要这样标记。命名空间别名是否为 news 无关紧要(它只是一个别名),但这可以通过以下方式控制XmlSerializerNamespaces 如果您愿意,则不需要 [Serialized]

例如,如果每个 需要位于“<”中。 a href="http://www.google.com/schemas/sitemap-news/0.9" rel="nofollow">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" 别名作为“新闻”,然后:

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>

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>
司马昭之心 2024-12-16 21:46:17

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

请参阅下面的完整代码

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

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());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文