简体   繁体   English

C#XML序列化元素名称空间

[英]C# XML Serialization Element namespace

I'm trying to serialize some c# classes to xml for an RSS feed. 我正在尝试将一些c#类序列化为RSS提要的xml。 I have one remaining issue, the thumbnail element needs media as a namespace and I've been unable to figure out how to add it correctly. 我还有一个问题,缩略图元素需要媒体作为命名空间,但我一直无法弄清楚如何正确添加它。 Right now I have it working with a string replace but I would rather do it the right way. 现在,我可以使用字符串替换操作,但是我宁愿使用正确的方法。 I don't think it matters but i'm working with Umbraco. 我认为这并不重要,但我正在与Umbraco合作。

What my code currently generates: 我的代码当前生成的内容是:

<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:media="http://search.yahoo.com/mrss" version="2.0">
  <channel>
    <title>blog.example.com</title>
    <link>http://blog.example.com/</link>
    <description />
    <item>
      <title>Fake Post 1</title>
      <link>http://www.example.com/post-1</link>
      <description />
      <pubDate>Thu, 25 Sep 2014 07:38:15 GMT</pubDate>
      <guid isPermaLink="false">http://www.example.com/post-1</guid>
      <media_x003A_thumbnail url="http://www.example.com/post-1/1.png" width="9001" height="9001" />
    </item>
    <item>
      <title>Fake Post 2</title>
      <link>http://www.example.com/post-2</link>
      <description />
      <pubDate>Thu, 25 Sep 2014 07:38:15 GMT</pubDate>
      <guid isPermaLink="false">http://www.example.com/post-2</guid>
      <media_x003A_thumbnail url="http://www.example.com/post-2/2.png" width="9001" height="9001" />
    </item>
  </channel>
</rss>

What I want my code to generate: 我希望我的代码生成:

<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:media="http://search.yahoo.com/mrss" version="2.0">
  <channel>
    <title>blog.example.com</title>
    <link>http://blog.example.com/</link>
    <description />
    <item>
      <title>Fake Post 1</title>
      <link>http://www.example.com/post-1</link>
      <description />
      <pubDate>Thu, 25 Sep 2014 07:38:15 GMT</pubDate>
      <guid isPermaLink="false">http://www.example.com/post-1</guid>
      <media:thumbnail url="http://www.example.com/post-1/1.png" width="9001" height="9001" />
    </item>
    <item>
      <title>Fake Post 2</title>
      <link>http://www.example.com/post-2</link>
      <description />
      <pubDate>Thu, 25 Sep 2014 07:38:15 GMT</pubDate>
      <guid isPermaLink="false">http://www.example.com/post-2</guid>
      <media:thumbnail url="http://www.example.com/post-2/2.png" width="9001" height="9001" />
    </item>
  </channel>
</rss>

c# classes (originally generated using "paste as xml classes" but I had to modify it a bit: c#类(最初使用“粘贴为xml类”生成,但我必须对其进行一些修改:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Web;
using System.Xml;
using System.Xml.Serialization;


/// <remarks/>
[XmlRoot("rss")]
[XmlTypeAttribute(AnonymousType = true)]
public partial class rss {

  private rssChannel channelField;

  private string versionField;

  private string mediaField;

  /// <remarks/>
  public rssChannel channel {
    get {
      return this.channelField;
    }
    set {
      this.channelField = value;
    }
  }

  /// <remarks/>
  [XmlAttributeAttribute()]
  public string version {
    get {
      return this.versionField;
    }
    set {
      this.versionField = value;
    }
  }

  [XmlNamespaceDeclarations]
  public XmlSerializerNamespaces xmlns;

}

/// <remarks/>
[XmlTypeAttribute(AnonymousType = true)]
public partial class rssChannel {

  private string titleField;

  private string linkField;

  private string descriptionField;

  private rssChannelItem[] itemField;

  /// <remarks/>
  public string title {
    get {
      return this.titleField;
    }
    set {
      this.titleField = value;
    }
  }

  /// <remarks/>
  public string link {
    get {
      return this.linkField;
    }
    set {
      this.linkField = value;
    }
  }

  /// <remarks/>
  public string description {
    get {
      return this.descriptionField;
    }
    set {
      this.descriptionField = value;
    }
  }

  /// <remarks/>
  [XmlElementAttribute("item")]
  public rssChannelItem[] item {
    get {
      return this.itemField;
    }
    set {
      this.itemField = value;
    }
  }
}

/// <remarks/>
[XmlTypeAttribute(AnonymousType = true)]
public partial class rssChannelItem {

  private string titleField;

  private string linkField;

  private string descriptionField;

  private string pubDateField;

  private rssChannelItemGuid guidField;

  private rssChanelItemMediaThumbnail mediaThumbnailField;

  /// <remarks/>
  public string title {
    get {
      return this.titleField;
    }
    set {
      this.titleField = value;
    }
  }

  /// <remarks/>
  public string link {
    get {
      return this.linkField;
    }
    set {
      this.linkField = value;
    }
  }

  /// <remarks/>
  public string description {
    get {
      return this.descriptionField;
    }
    set {
      this.descriptionField = value;
    }
  }

  /// <remarks/>
  public string pubDate {
    get {
      return this.pubDateField;
    }
    set {
      this.pubDateField = value;
    }
  }

  /// <remarks/>
  public rssChannelItemGuid guid {
    get {
      return this.guidField;
    }
    set {
      this.guidField = value;
    }
  }

  //hack TODO fix
  [XmlElement(ElementName = "media:thumbnail")]
  public rssChanelItemMediaThumbnail mediaThumbnail {
    get {
      return this.mediaThumbnailField;
    }
    set {
      this.mediaThumbnailField = value;
    }
  }

}

/// <remarks/>
[XmlTypeAttribute(AnonymousType = true)]
public partial class rssChannelItemGuid {

  private bool isPermaLinkField;

  private string valueField;

  /// <remarks/>
  [XmlAttributeAttribute()]
  public bool isPermaLink {
    get {
      return this.isPermaLinkField;
    }
    set {
      this.isPermaLinkField = value;
    }
  }

  /// <remarks/>
  [XmlTextAttribute()]
  public string Value {
    get {
      return this.valueField;
    }
    set {
      this.valueField = value;
    }
  }
}

[XmlTypeAttribute(AnonymousType = true)]
public partial class rssChanelItemMediaThumbnail {

  private string urlField;

  private string widthField;

  private string heightField;

  /// <remarks/>
  [XmlAttributeAttribute()]
  public string url {
    get {
      return this.urlField;
    }
    set {
      this.urlField = value;
    }
  }

  /// <remarks/>
  [XmlAttributeAttribute()]
  public string width {
    get {
      return this.widthField;
    }
    set {
      this.widthField = value;
    }
  }

  /// <remarks/>
  [XmlAttributeAttribute()]
  public string height {
    get {
      return this.heightField;
    }
    set {
      this.heightField = value;
    }
  }

}

functions that build the xml: 构建xml的函数:

/// <summary>
/// Create a BlogRssFeedModel
/// </summary>
/// <param name="content"></param>
/// <param name="culture"></param>
/// <returns></returns>
public static BlogRssFeedModel CreateBlogRssFeedModel(IPublishedContent content, CultureInfo culture) {
  IPublishedContent blogHomePage = content.AncestorsOrSelf(1).FirstOrDefault();
  BlogRssFeedModel blogRssFeedModel = new BlogRssFeedModel(content, culture);
  List<String> validDocumentTypes = new List<String>() { "BlogEntry" };
  List<IPublishedContent> blogPosts = blogHomePage.Descendants().Where(x => validDocumentTypes.Contains(x.DocumentTypeAlias)).OrderByDescending(x => x.GetPropertyValue<DateTime>("sortDate")).ToList();
  rss blogRssFeed = new rss();
  blogRssFeed.version = "2.0";
  blogRssFeed.xmlns = new XmlSerializerNamespaces();
  blogRssFeed.xmlns.Add("media", "http://search.yahoo.com/mrss");
  blogRssFeed.channel = new rssChannel();
  blogRssFeed.channel.title = blogHomePage.Name;
  blogRssFeed.channel.description = blogHomePage.GetPropertyValue<string>("pageDescription");
  blogRssFeed.channel.link = blogHomePage.Url;
  blogRssFeed.channel.item = blogPosts.Select(x => CreateRssChannelItem(x)).ToArray();
  //some (terrible) manual string hacks TODO fix this bs
  //string blogXml = CreateBlogXml(blogRssFeed).Replace("_x003A_", ":");
  string blogXml = CreateBlogXml(blogRssFeed);
  blogRssFeedModel.content = new HtmlString(blogXml);
  return blogRssFeedModel;
}

/// <summary>
/// Create a rssChannelItem for the blog's rss feed.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public static rssChannelItem CreateRssChannelItem(IPublishedContent x) {
  rssChannelItem element = new rssChannelItem();
  element.description = x.GetPropertyValue<string>("excerpt");
  element.link = x.Url;
  element.title = x.Name;
  element.pubDate = x.GetPropertyValue<DateTime>("sortDate").ToString("r");
  element.guid = new rssChannelItemGuid() { isPermaLink = false, Value = x.Url };
  element.mediaThumbnail = new rssChanelItemMediaThumbnail() { height = "", width = "", url = "" }; //to do populate data
  return element;
}

public static string CreateBlogXml(rss node) {
  System.Xml.Serialization.XmlSerializer xSerial = new System.Xml.Serialization.XmlSerializer(node.GetType());
  var xns = new XmlSerializerNamespaces();
  xns.Add("", "");
  MemoryStream ms = new MemoryStream();
  XmlTextWriter xmlTextWriter = new XmlTextWriter(ms, Encoding.UTF8);
  xmlTextWriter.Formatting = Formatting.Indented;
  xSerial.Serialize(xmlTextWriter, node, xns);
  ms = (MemoryStream)xmlTextWriter.BaseStream;
  return Encoding.UTF8.GetString(ms.ToArray());
}

Here: 这里:

[XmlElement(ElementName = "media:thumbnail")]

This is erroneous; 这是错误的。 the element name is thumbnail ; 元素名称thumbnail ; the namespace is http://search.yahoo.com/mrss . 命名空间http://search.yahoo.com/mrss media is just a namespace alias. media只是名称空间别名。 So the first thing we should do is fix that: 因此,我们应该做的第一件事就是修复该问题:

[XmlElement(ElementName = "thumbnail", Namespace = "http://search.yahoo.com/mrss")]

You are already adding the media namespace to blogRssFeed.xmlns : 您已经将media名称空间添加到blogRssFeed.xmlns

blogRssFeed.xmlns.Add("media", "http://search.yahoo.com/mrss");

so the rest should already work from there. 所以其余的应该已经可以从那里工作了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM