i am currently working on a project where i need the c# Xml Serialization.
My Problem: I havea class called ClassA. It has a Name Property which i would like to serialize in the Xml-File.
public class ClassA : BaseClass
{
[XmlElement("name")]
public string Name
{
get { return GetProperty(() => Name); }
set { SetProperty(() => Name, value); }
}
}
So when i serialize this with this serializer
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);
}
}
i get a xml-file like this
<ClassA Id="5eda8e4c-0698-4e07-9d20-7985964786f9" >
<name>Description</name>
</ClassA>
So my Question: I would like to have a xml like
<ClassA Id="5eda8e4c-0698-4e07-9d20-7985964786f9" >
<name><text>Description</text></name>
</ClassA>
How can i make this? I dont want to create a new class for the Name-Property..
Thanks :)
One possibility would be to turn Name
into a complex class; for example:
[XmlElement("name")]
public MyText Name
{
get { return GetProperty(() => Name); }
set { SetProperty(() => Name, value); }
}
Then you could define MyText
as:
public class MyText
{
public string Text {get;set;}
}
You can use 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;
}
}
}
Alternatively, if you want to stick to object deserialization, you should get the exact matching-to-xml class, so refer to this:
You could implement custom serialisation, the ClassA would need to implement ISerializable
. Alternatively implement the custom serialization using ISerializationSurrogate
and its related interfaces.
However that is not something I'd do. Its likely going to be much more complicated than having a wrapper class for Name.
You can customize serialization process. For example ClassA
could be decorated with attribute:
public class ClassA : BaseClass, IXmlSerializable
{
[XmlElement("name/text")]
public string Name
{
get { return GetProperty(() => Name); }
set { SetProperty(() => Name, value); }
}
}
Then the BaseClass
class should implement IXmlSerializable
like this:
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)
{
}
}
The result of serialization will be:
<ClassA>
<name>
<text>text-value</text>
</name>
</ClassA>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.