序列化List <object>列表项的属性是XML

时间:2015-05-15 08:05:33

标签: c# xml serialization xml-serialization

我不知道主题是否正确,如果不是,请纠正。到目前为止,我不确定要搜索我的问题,所以可能之前已经回答了这个问题。

目前我有以下课程(例如):

[Serializable]
public class Sample
{
    public string Something { get; set; }
    public List<Parameter> Parameters { get; set; }
}


[Serializable]
public class Parameter
{
    public string Name { get; set; }
    public string Value { get; set; }
}

这个结构我必须序列化为以下XML:

<Sample>
   <Something>1234512345112345</Something>  
   <Parameters>
     <Name>Value</Name>
     <Name>Value</Name>
   </Parameters>
 </Sample>

因此XML应该包含属性&#34; Name&#34;的属性值。作为XML元素名称。

2015年5月20日更新 我有以下XML内容:

 <?xml version="1.0" encoding="utf-16" ?> 
 <ProcessData>
 <ID>123456</ID> 
  <IDYTPE>BASEPLATE</IDYTPE> 
  <State>FAIL</State> 
  <Recipe>654321</Recipe> 
 <ProcessDataParameter>
  <test_0>0</test_0> 
  <test_1>12,34</test_1> 
  <test_2>24,68</test_2> 
  <test_3>37,02</test_3> 
  <test_4>49,36</test_4> 
  <test_5>61,7</test_5> 
  </ProcessDataParameter>
  </ProcessData>

当我尝试使用以下代码进行反序列化时:

 public void ReadXml(XmlReader reader)
        {
            reader.ReadStartElement("ProcessData");

            this.Id = reader.ReadElementString("ID");
            this.IdType = reader.ReadElementString("IDYTPE");
            this.State = reader.ReadElementString("State");
            this.Recipe = reader.ReadElementString("Recipe");

            reader.ReadStartElement("ProcessDataParameter");
            this.ProcessDataParameter = new List<ProcessDataParameter>();

            var subTree = reader.ReadSubtree();

            while (subTree.Read())
            {
                if (subTree.NodeType == XmlNodeType.Text)
                {
                    var nm = subTree.LocalName;
                    //Parameters.Add(new Parameter { Name = nm, Value = subTree.Value });

                }
            }

            reader.ReadEndElement();

        }

对于过程数据参数,所有内容都会被读出来。

似乎subTree.Read()只是从XML内容中重新元素而不是包含在中的所有元素。

在while循环中,读者会浏览以下值( debuged

  • test_0(开始标记)
  • 0(标签之间的值)
  • test_0(结束标记

然后不说了。 似乎读者将其视为一个子树。 此外,只有0值被识别为XmlNodeType.Text

2 个答案:

答案 0 :(得分:1)

您可以实施IXmlSerializable并为Sample类创建自己的自定义序列化行为。所以在你的情况下,这样的事情应该起作用

[Serializable]
public class Sample : IXmlSerializable
{
    public string Something { get; set; }
    public List<Parameter> Parameters { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);

        Something = doc.SelectSingleNode(@"/Sample/Something").FirstChild.Value;

        var parameters = doc.SelectSingleNode(@"/Sample/Parameters");
        if (parameters.HasChildNodes)
        {
            Parameters = new List<Parameter>();
            foreach (XmlElement childNode in parameters.ChildNodes)
            {
                Parameters.Add(new Parameter {Name = childNode.LocalName, Value = childNode.FirstChild.Value});
            }
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Something", this.Something);
        writer.WriteStartElement("Parameters");
        foreach (var parameter in Parameters)
        {
            writer.WriteElementString(parameter.Name, parameter.Value);
        }
        writer.WriteEndElement();
    }
}

更新以包含用于反序列化的ReadXml实现 我不太确定ReadXml是否完整,因为我现在无法对此进行测试,您可能需要对参数调整一下

答案 1 :(得分:-2)

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            Sample sample = new Sample(){
                Something = "1234512345112345",
                Parameters = new List<Parameter>(){
                    new Parameter(){
                        Name = new List<string>(){"Value", "Value"}
                    }
                }
            };

            XmlSerializer serializer = new XmlSerializer(typeof(Sample));

            StreamWriter writer = new StreamWriter(FILENAME);
            serializer.Serialize(writer, sample);
            writer.Flush();
            writer.Close();
            writer.Dispose();

            XmlSerializer xs = new XmlSerializer(typeof(Sample));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            Sample newSample = (Sample)xs.Deserialize(reader);

        }
    }
    [XmlRoot("Sample")]
    public class Sample
    {
        [XmlElement("Something")]
        public string Something { get; set; }
        [XmlElement("Parameters")]
        public List<Parameter> Parameters { get; set; }
    }


    [XmlRoot("Parameters")]
    public class Parameter
    {
        [XmlElement("Name")]
        public List<string> Name { get; set; }
    }
}
​