【问题标题】:C# XML Serialization XMLElement PathC# XML 序列化 XMLElement 路径
【发布时间】:2018-10-30 22:20:57
【问题描述】:

我目前正在做一个需要 c# Xml 序列化的项目。

我的问题: 我有一个名为 ClassA 的课程。它有一个我想在 Xml 文件中序列化的名称属性。

 public class ClassA : BaseClass
{
    [XmlElement("name")]
    public string Name
    {
        get { return GetProperty(() => Name); }
        set { SetProperty(() => Name, value); }
    }
}

所以当我用这个序列化器序列化这个时

public class PetriNetXMLReader
{
    public void SaveToXML(PetriNetXML petriNet, string fileName)
    {
        System.Xml.Serialization.XmlSerializer writer =
       new System.Xml.Serialization.XmlSerializer(typeof(PetriNetXML));

           System.IO.FileStream file = System.IO.File.Create(fileName);

        writer.Serialize(file, petriNet);
        file.Close();
    }

    public PetriNetXML ReadFromXML(string fileName)
    {
        var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

        XmlSerializer deserializer = new XmlSerializer(typeof(PetriNetXML));
        return (PetriNetXML)deserializer.Deserialize(fileStream);



    }
}

我得到一个这样的 xml 文件

<ClassA Id="5eda8e4c-0698-4e07-9d20-7985964786f9" >
  <name>Description</name>
</ClassA>

所以我的问题: 我想要一个类似的xml

 <ClassA Id="5eda8e4c-0698-4e07-9d20-7985964786f9" >
  <name><text>Description</text></name>
</ClassA>

我怎样才能做到这一点?我不想为 Name-Property 创建一个新类..

谢谢:)

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    一种可能性是将Name 变成一个复杂的类;例如:

    [XmlElement("name")]
    public MyText Name
    {
        get { return GetProperty(() => Name); }
        set { SetProperty(() => Name, value); }
    }
    

    那么您可以将MyText 定义为:

    public class MyText
    {
        public string Text {get;set;}
    }
    

    【讨论】:

    • 我想我会这样做,这不是一个好的解决方案,但最快且没有开销!
    【解决方案2】:

    您可以使用 XMLReader:

    ClassA a = new ClassA();
    
    using (XmlTextReader reader = new XmlTextReader("books.xml"))
                {
    
                    while (reader.Read())
                    {
                        switch (reader.Name)
                        {
                            case "text":
                                //do something with this node, like:
                                a.Name = reader.Value;
                                break;
                        }
                    }
    
                }
    

    或者,如果你想坚持对象反序列化,你应该得到完全匹配到xml的类,所以参考这个:

    XML2CSharp

    【讨论】:

      【解决方案3】:

      您可以实现自定义序列化,ClassA 需要实现ISerializable。或者使用ISerializationSurrogate及其相关接口实现自定义序列化。

      但是,我不会这样做。它可能比为 Name 提供包装类要复杂得多。

      【讨论】:

        【解决方案4】:

        您可以自定义序列化过程。例如ClassA 可以用属性修饰:

        public class ClassA : BaseClass, IXmlSerializable
        {
            [XmlElement("name/text")]
            public string Name
            {
                get { return GetProperty(() => Name); }
                set { SetProperty(() => Name, value); }
            }
        }
        

        那么BaseClass 类应该像这样实现IXmlSerializable

        public class BaseClass : IXmlSerializable
        {
            public XmlSchema GetSchema()
            {
                return null;
            }
        
            public void ReadXml(XmlReader reader)
            {
                foreach (PropertyInfo propertyInfo in this.GetType().GetProperties())
                {
                    XmlElementAttribute elementAttribute = propertyInfo.GetCustomAttribute<XmlElementAttribute>(true);
        
                    if (elementAttribute != null)
                    {
                        string[] elementNames = elementAttribute.ElementName.Split('/', '\\');
        
                        foreach (string elementName in elementNames)
                        {
                            reader.ReadStartElement(elementName);
                        }
        
                        propertyInfo.SetValue(this, reader.ReadContentAsString());
        
                        foreach (string elementName in elementNames)
                        {
                            reader.ReadEndElement();
                        }
                    }
                }
            }
        
            public void WriteXml(XmlWriter writer)
            {
                foreach (PropertyInfo propertyInfo in this.GetType().GetProperties())
                {
                    XmlElementAttribute elementAttribute = propertyInfo.GetCustomAttribute<XmlElementAttribute>(true);
        
                    if (elementAttribute != null)
                    {
                        string[] elementNames = elementAttribute.ElementName.Split('/', '\\');
        
                        foreach (string elementName in elementNames)
                        {
                            writer.WriteStartElement(elementName);
                        }
        
                        writer.WriteString(propertyInfo.GetValue(this).ToString());
        
                        foreach (string elementName in elementNames)
                        {
                            writer.WriteEndElement();
                        }
                    }
                }
            }
        
            protected string GetProperty(Func<string> f)
            {
                return "text-value";
            }
        
            protected void SetProperty<T>(Func<T> f, T value)
            {
            }
        }
        

        序列化的结果是:

        <ClassA>
          <name>
            <text>text-value</text>
          </name>
        </ClassA>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-17
          • 2019-07-20
          相关资源
          最近更新 更多