将对象序列化为特定格式,删除名称空间和移动属性

时间:2015-02-12 16:57:20

标签: c# c#-4.0 serialization xml-serialization

我正在尝试为我的应用程序构建必须以特定格式导出数据的序列化,下面是预期的样本:

<?xml version="1.0" encoding="utf-8"?>
<sync>
  <table name="Test" diff="0" mode="db">
    <keys>
      <key>MY_NUMBER</key>
      <key>ID</key>
    </keys>
    <items task="modify">
      <item ID="OK" MY_NUMBER="two"/>
      <item ID="NT" MY_NUMBER="two"/>
    </items>
  </table>
  <table name="Second" diff="1" mode="x">
    <keys>
      <key>ID</key>
    </keys>
    <items task="add">
      <item ID="x" TYPE="c"/>
    </items>
  </table>
</sync>

我得到了类似的结果:

<?xml version="1.0" encoding="utf-8"?>
<sync>
  <table name="Test" diff="0" mode="db" task="modify">
    <keys>
      <key>MY_NUMBER</key>
      <key>ID</key>
    </keys>
    <items>
      <item d4p1:type="FirstItem" ID="OK" MY_NUMBER="two" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
      <item d4p1:type="FirstItem" ID="NT" MY_NUMBER="two" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
    </items>
  </table>
  <table name="SecondTest" diff="1" mode="x" task="add">
    <keys>
      <key>ID</key>
    </keys>
    <items>
      <item d4p1:type="SecondItem" ID="x" TYPE="c" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance" />
    </items>
  </table>
</sync>

但是我得到了不受欢迎的名称空间,我尝试搜索SO寻找解决方案(Omitting all xsi and xsd namespaces when serializing an object in .NET?Remove Namespaces During XML Serialization),但没有运气。

我的课程定义如下:

namespace Sync.Models
{
    [XmlRoot("sync")]
    [XmlInclude(typeof(FirstItem))]
    [XmlInclude(typeof(SecondItem))]
    public class Export
    {
        [XmlElement(ElementName = "table")]
        public Table users { get; set; }

        [XmlElement(ElementName = "table2")]
        public Table items { get; set; }
    }

    public class Table
    {
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlAttribute("diff")]
        public int diff { get; set; }
        [XmlAttribute("mode")]
        public string mode { get; set; }

        [XmlArray("keys")]
        [XmlArrayItem("key")]
        public List<string> Keys { get; set; }

        [XmlArray("items")]
        [XmlArrayItem("item")]
        public List<BaseItem> Items { get; set; }

        [XmlAttribute("task")]
        public string Task { get; set; }
    }

    public class FirstItem:BaseItem
    {
        [XmlAttribute("MY_NUMBER")]
        public string Number { get; set; }
    }
    public class SecondItem:BaseItem
    {
        [XmlAttribute("TYPE")]
        public string Type { get; set; }
    }
}

最后我的序列化功能:

var testData = new Export
{
    users = new Table
    {
        name = "Test",
        diff = 0,
        mode = "db",
        Keys = new List<string> { "MY_NUMBER", "ID" },
        Items = new List<BaseItem>
        {

            new FirstItem {Id = "OK", Number = "two"},
            new FirstItem {Id = "NT", Number = "two"}
        },
        Task = "modify"
    },
    items = new Table
    {
        name = "SecondTest",
        diff = 1,
        mode = "x",
        Keys = new List<string> { "ID" },
        Items = new List<BaseItem>
        {
            new SecondItem{Id = "x",Type = "c"}
        },
        Task = "add"
    }
};


var fileName_tmp = String.Format(@"{0}\xml1.xml", Application.StartupPath);
var fileName = String.Format(@"{0}\xml.xml", Application.StartupPath);

var serializer = new XmlSerializer(typeof(Export));
using (TextWriter writer = new StreamWriter(fileName_tmp))
{
    serializer.Serialize(writer, testData, new XmlSerializerNamespaces(new[] {XmlQualifiedName.Empty}));
}

using (FileStream inputStream = File.OpenRead(fileName_tmp))
{
    using (StreamReader inputReader = new StreamReader(inputStream))
    {
        using (StreamWriter outputWriter = File.CreateText(fileName))
        {
            string tempLineValue;
            while (null != (tempLineValue = inputReader.ReadLine()))
            {
                outputWriter.WriteLine(tempLineValue.Replace("table2", "table"));
            }
        }
    }
}

1。我想从节点中删除不需要的命名空间和类型属性,但正如我在解决方案之前写的那样,我发现它不起作用。
2。我需要有多个具有相同名称的节点(table),现在我唯一的解决方案是在序列化后替换标记。我知道我可以使用List来存储表格,但在序列化期间,这给了我一个额外的不需要的级别 - 这可以删除吗?或者自定义序列化只是选项?
3。现在表中的Task属性存储为xml中表节点的属性。我可以将其移至items,以获得理想的结果吗?或者我必须创建自定义序列化吗?

1 个答案:

答案 0 :(得分:0)

您可以通过添加此代码来删除命名空间

using (FileStream stream = new FileStream("FilePath",FileMode.Create))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(YourClass));
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");                    
                    serializer.Serialize(stream," Your Object to Serialize",ns);
                }