1

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?
dinotom
  • 4,990
  • 16
  • 71
  • 139

2 Answers2

0

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>
Mutlu Kaya
  • 129
  • 7
0

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();
Yuck
  • 49,664
  • 13
  • 105
  • 135
  • @Yuck...since you are returning a string...I assume then updating xml files is just a matter of appending to the end or inserting within a parent, the new element as a string to the current file? – dinotom Dec 08 '17 at 17:32
  • If you need to work with the XML you should use `XElement`, which can be loaded from the resulting string xml by calling `XElement.Parse(xml);`. – Yuck Dec 08 '17 at 17:58
  • @Yuck...Playing around with this I see it creates the Xml node header with an encoding attribute set to "UTF-16", ...is there an overload so I change that to UTF-8 rather than doing it manually (in other code)? – dinotom Dec 10 '17 at 14:45