C#XML序列化XMLElement路径

时间:2018-10-30 13:49:38

标签: c# xml

我目前正在从事需要C#Xml序列化的项目。

我的问题: 我有一堂课叫做ClassA。它具有一个Name属性,我想在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>

我该怎么做?我不想为“名称属性”创建一个新类。

谢谢:)

4 个答案:

答案 0 :(得分:1)

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

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

然后,您可以将MyText定义为:

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

答案 1 :(得分:0)

您可以使用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

答案 2 :(得分:0)

您可以实现自定义序列化,ClassA需要实现ggplot(df3, aes(x=zeitpunkt, y=weight, group=group, color=group)) + geom_rect(df3, mapping=aes(xmin=-0.5, xmax=13, ymin=-Inf, ymax=+Inf), fill="yellow", alpha=0.01, inherit.aes = FALSE) + geom_line() + geom_point() + geom_errorbar(aes(ymin=weight-sd, ymax=weight+sd), width=.2) + labs(x="Zeit in Wochen", y = "Gewicht in g") + scale_color_brewer(palette="Paired")+theme_minimal() + labs(colour="Gruppe") 。或者,使用ISerializable及其相关接口来实现自定义序列化。

但是那不是我要做的。它可能比拥有Name的包装器类要复杂得多。

答案 3 :(得分:0)

您可以自定义序列化过程。例如,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>