【问题标题】:XML Serialization on complex object复杂对象的 XML 序列化
【发布时间】:2013-11-13 21:27:12
【问题描述】:

我一直在研究如何将 C# 类序列化为 XML 文件,但只找到了非常基本的示例。我正在尝试序列化一个包含其他类的类。

更具体地说,我有一个确定性有限自动机类,我在其中封装了一个转换列表、TotalStates 和 Alphabet。其中Transitions 和States 也被定义为C# 类。

在尝试按原样序列化类之后,输出 XML 文件是空白的,所以我猜我需要做一些额外的工作才能让封装的类也能正常工作。我需要什么才能将所有封装的用户定义类也放入 XML 中。

这是我试图序列化的类。现在我的属性没有初始化。

  public class XMLDoc
    {
        public XMLDoc()
        {
            AllStates = new List<State>();
            alphabet = new List<char>();
            transitions = new List<Transition>();

            alphabet.Add('1');
            alphabet.Add('0');


        }
        List<State> AllStates; // Our set of all States
        List<Char> alphabet;    // Our alphabet set
        List<Transition> transitions; //; Our set of transitions
        State startState, finalState;
    }

这是一个状态类

  public class State
    {
        public State(int value)
        {
            id = value;
            type = StateType.Normal;
        }

        public void makeInitial()
        {
            type = StateType.Initial;
        }

        public void makeFinal()
        {
            type = StateType.Final;
        }
        public int getID()
        {
            return this.id;
        }

        int id;
        StateType type;

        List<Transition> transitions; // This list is going to be all transitions that have this State as the Initial value
    }

这是一个过渡类

  public class Transition
    {
        public Transition(State initial, Char accept, State final)
        {
            this.init = initial;
            this.acceptor = accept;
            this.final = final;
        }

        public int getInit(){
            return init.getID();
        }

        public int getFinal()
        {
            return final.getID();
        }

        public Char getAcceptor()
        {
            return acceptor;
        }
        State init; // This is the state we are transitioning
        Char acceptor; // This is the accepting alphabet value
        State final; // This is the state init becomes after accepting the acceptor
    }

最后,我想要类似于这个形式的XML

<?xml version='1.0' ?>

<!-- XML Definition of a DFA by Matt Hintzke -->
<DFA>
    <!-- This defines the all used states in the DFA -->
    <STATES-SET>
        <STATE>q0</STATE>
        <STATE>q1</STATE>
        <STATE>q2</STATE>
        <STATE>q3</STATE>
    </STATES-SET>

    <!-- This defines the alphabet -->
    <ALPHABET>
        <CHARACTER>1</CHARACTER>
        <CHARACTER>0</CHARACTER>
    </ALPHABET>

    <!-- This defines all transitions -->
    <TRANSITION-SET>

        <!-- A transition block represents all transitions that can be made from a single initial state -->
        <TRANSITION-BLOCK>
            <!-- Hence, this block defines all transitions from the INIT-STATE q0 to any other states -->
            <INIT-STATE>q0</INIT-STATE>
            <!-- A transition represents any ACCEPTOR character from the INIT-STATE to some FINAL state -->
            <TRANSITION>
                <ACCEPTOR>1</ACCEPTOR>
                <FINAL>q1</FINAL>
            </TRANSITION>

            <TRANSITION>
                <ACCEPTOR>0</ACCEPTOR>
                <FINAL>q2</FINAL>
            </TRANSITION>
        </TRANSITION-BLOCK>



        <TRANSITION-BLOCK>
            <INIT-STATE>q1</INIT-STATE>
            <TRANSITION>
                <ACCEPTOR>1</ACCEPTOR>
                <FINAL>q0</FINAL>
            </TRANSITION>

            <TRANSITION>
                <ACCEPTOR>0</ACCEPTOR>
                <FINAL>q3</FINAL>
            </TRANSITION>
        </TRANSITION-BLOCK>


        <TRANSITION-BLOCK>
            <INIT-STATE>q2</INIT-STATE>
            <TRANSITION>
                <ACCEPTOR>1</ACCEPTOR>
                <FINAL>q3</FINAL>
            </TRANSITION>

            <TRANSITION>
                <ACCEPTOR>0</ACCEPTOR>
                <FINAL>q0</FINAL>
            </TRANSITION>
        </TRANSITION-BLOCK>



        <TRANSITION-BLOCK>
            <INIT-STATE>q3</INIT-STATE>
            <TRANSITION>
                <ACCEPTOR>1</ACCEPTOR>
                <FINAL>q2</FINAL>
            </TRANSITION>

            <TRANSITION>
                <ACCEPTOR>0</ACCEPTOR>
                <FINAL>q1</FINAL>
            </TRANSITION>
        </TRANSITION-BLOCK>
    </TRANSITION-SET>


    <!-- This defines all starting states -->
    <STARTING-SET>
        <STATE>q0</STATE>
    </STARTING-SET>

    <!-- This defines all final states -->
    <FINAL-SET>
        <STATE>q3</STATE>
    </FINAL-SET>
</DFA>

最后,这里是序列化的代码...

    public void Serialize()
    {
        XMLDoc mydoc = new XMLDoc();

        XmlSerializer ser = new XmlSerializer(typeof(XMLDoc));
        StreamWriter writer = new StreamWriter("test.xml");
        ser.Serialize(writer, mydoc);
        writer.Close();
    }

【问题讨论】:

  • 请出示您正在使用的代码。
  • 你有什么问题?
  • 您正在尝试对一个对象进行 XML 序列化。如果您希望我们帮助您,您将不得不展示执行序列化的实际代码。
  • 初步观察 - 您不能序列化字段,只能序列化属性。另外,我们可以看看你的实际序列化代码吗?
  • 添加了所有相关内容

标签: c# xml-serialization


【解决方案1】:

这些类不会序列化,因为您有私有字段,但您需要使用公共属性。

更新: 下面是一个基于您的类在 LinqPad 中运行的示例(我删除了这些方法,因为它们与序列化无关):

void Main()
{
     XMLDoc mydoc = new XMLDoc();

        XmlSerializer ser = new XmlSerializer(typeof(XMLDoc));
        StreamWriter writer = new StreamWriter(@"D:\test.xml");
        ser.Serialize(writer, mydoc);
        writer.Close();
}

public class XMLDoc
    {
        public XMLDoc()
        {
            AllStates = new List<State>();
            alphabet = new List<char>();
            transitions = new List<Transition>();
            alphabet.Add('1');
            alphabet.Add('0');
        }
        public List<State> AllStates{get;set;} // Our set of all States
        public List<Char> alphabet{get;set;}    // Our alphabet set
        public List<Transition> transitions{get;set;} //; Our set of transitions
        public State startState{get;set;}
        public State finalState{get;set;}
    }


     public class State
     {
      //note - no explicitly defined default ctor here
      //that is OK as long as you don't have any other ctors defined.
      //although bear in mind that you probably should have one
      //to intialise 'type' and 'transitions'
      public int id{get;set;}
      public StateType type{get;set;}
      public List<Transition> transitions{get;set;} // This list is going to be all transitions that have this State as the Initial value
     }


    public class StateType
    {
      //did not have any code for this class...
    }

    public class Transition
    {
        public Transition(){} //must have default ctor to serialise.
        public Transition(State initial, Char accept, State final)
        {
            this.init = initial;
            this.acceptor = accept;
            this.final = final;
        }        
        public State init{get;set;} // This is the state we are transitioning
        public Char acceptor{get;set;} // This is the accepting alphabet value
        public State final{get;set;} // This is the state init becomes after accepting the acceptor
    }

这会产生:

<?xml version="1.0" encoding="utf-8"?>
<XMLDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AllStates />
  <alphabet>
    <char>49</char>
    <char>48</char>
  </alphabet>
  <transitions />
</XMLDoc>

请注意,您应该检查各种Serialisation Attributes,您可以使用这些Serialisation Attributes 来控制生成的 XML 的“形状”,但老实说,我不是 100% 确定您可以使用默认格式实现您想要的格式XMLSerializer。

您可能会考虑查看 XDocument 类,该类可用于从 System.Xml.Linq(Linq 到 XML)非常轻松地构建 XML 文档 - 它可能更适合您想要的格式类型。

希望对您有所帮助。

【讨论】:

  • 那么这是否意味着我必须公开我所有班级中的每个属性?
  • 要么这样做,要么编写自己的自定义序列化程序。(这并不难)
  • 当我在前面添加 public 时,我的 XMLSerializer() 构造函数在 InvalidOperationException 上中断
  • @Matt,您得到的内部异常表明 Transition 缺少默认 ctor。我已经用一个工作示例更新了我的答案
  • 哦,谢谢,但添加到我的后,它不会改变任何东西
猜你喜欢
  • 1970-01-01
  • 2015-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多