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

eba*_*lga 4 c# xml-serialization google-sitemap

我想像这样序列化

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
</urlset>
Run Code Online (Sandbox Code Playgroud)

但产生了错误的结果.

我的班级在这里

[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; }
}
Run Code Online (Sandbox Code Playgroud)

Serializer就在​​这里

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

    }
Run Code Online (Sandbox Code Playgroud)

结果就在这里

<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"/>
Run Code Online (Sandbox Code Playgroud)

我的班级宣言有什么问题?

另一个问题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>
Run Code Online (Sandbox Code Playgroud)

我的声明在这里

[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; }
    }
Run Code Online (Sandbox Code Playgroud)

这是返回错误

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

Mar*_*ell 8

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

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

你可以拿走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 "别名为"新闻",然后:

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; }
}
Run Code Online (Sandbox Code Playgroud)

这会产生:

<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>
Run Code Online (Sandbox Code Playgroud)

(我还没有检查实际的内容命名空间是什么 - 这只是为了显示数据中的命名空间,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; }
}
Run Code Online (Sandbox Code Playgroud)

产生:

<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>
Run Code Online (Sandbox Code Playgroud)