简体   繁体   中英

XmlSerializer to convert to XmlElement or string

I am storing developer notes in XML files within the project, to eliminate storing them on a SQL instance to reduce database calls.

I have my class set up to be Serialized

[Serializable]
public class NoteDto 
{
    [NonSerialized]
    private string _project;

    public string Date { get; set; }
    public string Time { get; set; }
    public string Author { get; set; }
    public string NoteText { get; set; }
    public string Project
    {
        get => _project;
        set => _project = value;
    }       
}

to create this element

<Note>
  <Date></Date>
  <Time></Time>
  <NoteText></NoteText>
  <Author></Author>
</Note>

The reason I do not want Project property serialized, is that the Note Element is in a parent element (NotesFor).

<NotesFor id="project value here">
  // note element here
</NotesFor>

I need the Project string to search for the Node where the NotesFor element id = Project then append the created element to the end of its children.

So that leaves two questions

  1. Do I create an XElement and append to current node or do I create a string to append to the node in the Xml file? I don't work much with Xml so I am not sure what the standard protocol is to update Xml files.
  2. Is there a better way to accomplish what I am trying to do?

As I understood, your data is small enough to store it in xml file(s). Xml files are stored in the file system and even you use XmlDocument or XDocument to load and save an xml file, whole of the file would be re-written to the file system.

I think It's better to use objects (NoteForDto & NoteDto) and XmlSerializer to write file. So you don't have to work with X(ml)Document complexity. Here is the example .
And your code sample:

    public class NoteDto
    {

        private string _project;

        public string Date { get; set; }
        public string Time { get; set; }
        public string Author { get; set; }
        public string NoteText { get; set; }

        [XmlIgnore]
        public string Project
        {
            get => _project;
            set => _project = value;
        }
    }

    [XmlRoot(ElementName = "NotesFor")]
    public class NotesForDto
    {
        [XmlAttribute(AttributeName="id")]
        public string ProjectID { get; set; }

        [XmlElement(ElementName ="Note")]            
        public List<NoteDto> NoteList { get; set; }
    }

    public static void Main(string[] args)
    {
        var notes = new NotesForDto
        {
            ProjectID = "SampelProject",
            NoteList = new List<NoteDto>
           {
               new NoteDto
               {
                   Author="Author1",
                   Date= "Date1",
                   NoteText="NoteText1",
                   Project="SampleProject",
                   Time="Time1"
               },
               new NoteDto
               {
                   Author="Author2",
                   Date= "Date2",
                   NoteText="NoteText2",
                   Project="SampleProject",
                   Time="Time2"
               }
           }
        };            

        XmlSerializer ser = new XmlSerializer(typeof(NotesForDto));

        using (var tw = File.Open("notes.xml",FileMode.Create))
        {
            ser.Serialize(tw,notes);
        }                
    }

Output (notes.xml)

<?xml version="1.0"?>
<NotesFor xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="SampelProject">
  <Note>
    <Date>Date1</Date>
    <Time>Time1</Time>
    <Author>Author1</Author>
    <NoteText>NoteText1</NoteText>
  </Note>
  <Note>
    <Date>Date2</Date>
    <Time>Time2</Time>
    <Author>Author2</Author>
    <NoteText>NoteText2</NoteText>
  </Note>
</NotesFor>

You don't need to mark the class serializable.

public class NoteDto 
{
    public string Date { get; set; }
    public string Time { get; set; }
    public string Author { get; set; }
    public string NoteText { get; set; }
    [XmlIgnore]
    public string Project { get; set; }
}

You can serialize this with the following code, which I've implemented as an extension method:

public static string ToXml<T>(this T thing)
{
    if (thing == null)
        return null;

    var builder = new StringBuilder();

    new XmlSerializer(typeof(T)).Serialize(new StringWriter(builder), thing);

    return builder.ToString();
}

Which gets used like this:

var note = new NoteDto
{
    Date = "1/1/2018",
    Time = "4:00 PM",
    Author = "Some Guy",
    NoteText = "My Note",
    Project = "A Project"
};
var xml = note.ToXml();

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM