c# – 带有IXmlSerializable的命名空间前缀

前端之家收集整理的这篇文章主要介绍了c# – 带有IXmlSerializable的命名空间前缀前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
对使用的适当装饰器或可能需要的任何设计感到困惑.序列化实现IXmlSerializable的类是否有办法在XmlRoot元素中包含命名空间及其前缀?

例如,类定义.

  1. using System;
  2. using System.Xml;
  3. using System.Xml.Schema;
  4. using System.Xml.Serialization;
  5. [XmlRoot("Classy",Namespace = XML_NS)]
  6. public class TestClass : IXmlSerializable
  7. {
  8. private const string XML_PREFIX = ""; // default namespace
  9. private const string XML_NS = "www.123.com";
  10. private const string XML_MEMBER_PREFIX = "me";
  11. private const string XML_MEMBER_NS = "member.com";
  12.  
  13. [XmlNamespaceDeclarations]
  14. public XmlSerializerNamespaces xmlsn {
  15. get {
  16. XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
  17. xsn.Add(XML_PREFIX,XML_NS);
  18. xsn.Add(XML_MEMBER_PREFIX,XML_MEMBER_NS);
  19. return xsn;
  20. }
  21. }
  22.  
  23. void IXmlSerializable.WriteXml(XmlWriter writer) {
  24. writer.WriteElementString(XML_MEMBER_PREFIX,"Member1.5",XML_MEMBER_NS,Member1);
  25. writer.WriteElementString(XML_MEMBER_PREFIX,"Member2.5",Member2.ToString());
  26. writer.WriteElementString(XML_PREFIX,"Member3.5",XML_NS,Member3);
  27. }
  28.  
  29. //[XmlElement(ElementName = "Member1.5",Namespace = XML_MEMBER_NS)]
  30. public string Member1 {
  31. get { return "init"; }
  32. set { ; }
  33. }
  34. //[XmlElement(ElementName = "Member2.5",Namespace = XML_MEMBER_NS)]
  35. public int Member2 {
  36. get { return 3; }
  37. set { ; }
  38. }
  39. //[XmlElement(ElementName = "Member3.5",Namespace = XML_NS)]
  40. public string Member3 {
  41. get { return "default namespace"; }
  42. set { ; }
  43. }
  44.  
  45. // ignore ReadXml/GetSchema
  46. XmlSchema IXmlSerializable.GetSchema() { return null; }
  47. void IXmlSerializable.ReadXml(XmlReader reader) { return; }
  48. }

通过以下序列化时:

  1. TestClass tc = new TestClass();
  2. XmlSerializer ser = new XmlSerializer(typeof(TestClass));
  3. ser(writer,tc,tc.xmlsn); // just a plain XmlWriter to Console.Out

输出

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Classy xmlns="www.123.com">
  3. <me:Member1.5 xmlns:me="member.com">init</me:Member1.5>
  4. <me:Member2.5 xmlns:me="member.com">3</me:Member2.5>
  5. <Member3.5>default namespace</Member3.5>
  6. </Classy>

我期待的输出是:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Classy xmlns:me="member.com" xmlns="www.123.com">
  3. <me:Member1.5>init</me:Member1.5>
  4. <me:Member2.5>3</me:Member2.5>
  5. <Member3.5>default namespace</Member3.5>
  6. </Classy>

第二个是XmlSerializer的输出,如果删除了类的IXmlSerializable实现并取消注释XmlElement装饰器.我知道返回的两个Xml文档都是有效的,但尝试删除冗余的命名空间声明会很好.我认为这样的事情是可能的,因为IXmlSerializable旨在更好地控制类的序列化/反序列化方式.

更新:一个非常有趣的答案建议修改XmlWriterSettings!看起来这会通过修改NamespaceHandling属性来清除所有内容.但是,这仍然会导致为每个成员重写名称空间.完整的序列化代码如下:

  1. XmlSerializer ser = new XmlSerializer(typeof(TestClass));
  2. TestClass tc = new TestClass();
  3.  
  4. XmlWriterSettings xmlSet = new XmlWriterSettings();
  5. xmlSet.Encoding = System.Text.Encoding.UTF8;
  6. xmlSet.Indent = true;
  7. xmlSet.NamespaceHandling = NamespaceHandling.OmitDuplicates;
  8. XmlWriter writer = XmlWriter.Create(Console.Out,xmlSet);
  9.  
  10. ser.Serialize(writer,tc); // with/without tc.xmlsn same result
  11. writer.Flush();
  12. writer.Close();

解决方法

我只是向WriteXml添加了一个String属性.有效!
  1. void IXmlSerializable.WriteXml(XmlWriter writer) {
  2. writer.WriteAttributeString("xmlns:me","member.com");
  3. writer.WriteAttributeString("xmlns","www.123.com");
  4. writer.WriteElementString(XML_MEMBER_PREFIX,Member3);
  5. }

并从类中删除[XmlRoot(“Classy”,Namespace = XML_NS)]和xmlsn属性.

猜你在找的C#相关文章