I have a program that creates an XML log. First I check if the XML exists, and if not I use the following code to create it:
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(myXMLLog, settings))
{
writer.WriteStartDocument();
writer.WriteComment("Comment here.");
writer.WriteStartElement("Batch");
writer.WriteAttributeString("ID", BatchID);
writer.WriteAttributeString("Date", now);
writer.WriteStartElement("Step");
writer.WriteElementString("Name", step);
writer.WriteElementString("Success", success);
writer.WriteElementString("Message", message);
writer.WriteStartElement("Transaction");
writer.WriteElementString("ID", transID);
writer.WriteElementString("Details", details);
writer.WriteEndElement();
writer.WriteEndDocument();
}
This works as expected and creates the file:
<!--This log was created by the Application.-->
<Batch Date="1/22/2014 10:01:11 PM" ID="166bf0d2-3bd4-4353-b309-20b6d0d59a93">
<Step>
<Name>Start Batch</Name>
<Success>1</Success>
<Message>Processing Batch</Message>
<Transaction>
<ID>N/A</ID>
<Details>N/A</Details>
</Transaction>
</Step>
So the second time around, it checks that the XML exists, it does, so instead of creating it should just add to it. I'm using the following code for this:
XDocument xmlDoc = XDocument.Load(myXMLLog);
XElement root = new XElement("Batch");
root.Add(new XAttribute("ID", BatchID));
root.Add(new XAttribute("Date", now));
root.Add(new XElement("Step"));
root.Add(new XAttribute("Name", step));
root.Add(new XAttribute("Success", success));
root.Add(new XAttribute("Message", message));
root.Add(new XElement("Transaction"));
root.Add(new XAttribute("ID", transID));
root.Add(new XAttribute("Details", details));
xmlDoc.Element("Batch").Add(root);
xmlDoc.Save(myXMLLog);
So now I'm expecting the XML file to look something like this:
<!--This log was created by the Application.-->
<Batch Date="1/22/2014 10:01:11 PM" ID="166bf0d2-3bd4-4353-b309-20b6d0d59a93">
<Step>
<Name>Start Batch</Name>
<Success>1</Success>
<Message>Processing Batch</Message>
<Transaction>
<ID>N/A</ID>
<Details>N/A</Details>
</Transaction>
</Step>
</Batch>
<Batch Date="1/22/2014 10:20:00 PM" ID="166bf0d2-3bd4-4353-b309-20b6d0d5aaa">
<Step>
<Name>Start Batch</Name>
<Success>1</Success>
<Message>Processing Batch</Message>
<Transaction>
<ID>N/A</ID>
<Details>N/A</Details>
</Transaction>
</Step>
</Batch>
But instead I get an exception "Duplicate Attribute".
What am I doing wrong?
Thanks!
EDIT:
The XML Document does has at the top of it. Valid XML would be very nice, but not a most.
EDIT EDIT:
This is how my code looks now:
if (File.Exists(myXMLLog))
{
XDocument xmlDoc = XDocument.Load(myXMLLog);
XElement root = new XElement("Batch",
new XAttribute("ID", BatchID),
new XAttribute("Date", now),
new XElement("Step",
new XElement("Name", step),
new XElement("Success", success),
new XElement("Message", message),
new XElement("Transaction",
new XAttribute("IDTrans", transID),
new XAttribute("Details", details))));
xmlDoc.Root.Add(root);
xmlDoc.Save(myXMLLog);
}
else
{
using (XmlWriter writer = XmlWriter.Create(myXMLLog, settings))
{
writer.WriteStartDocument();
writer.WriteComment("This log was created by the Application.");
writer.WriteStartElement("Batch");
writer.WriteAttributeString("ID", BatchID);
writer.WriteAttributeString("Date", now);
writer.WriteStartElement("Step");
writer.WriteElementString("Name", step);
writer.WriteElementString("Success", success);
writer.WriteElementString("Message", message);
writer.WriteStartElement("Transaction");
writer.WriteElementString("IDTrans", transID);
writer.WriteElementString("Details", details);
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
I'm ok with the format of the XML, my problem now is that is doing the BATCH inside the first BATCH
<Batch Date="1/22/2014 11:49:17 PM" ID="6966578b-b326-4f16-a315-1b4228a9fa42">
<Step><Name>Create DataTable</Name>
<Success>1</Success>
<Message>DataTable was Created and Populated</Message>
<Transaction>
<IDTrans>N/A</IDTrans>
<Details>0</Details>
</Transaction>
</Step>
<Batch Date="1/22/2014 11:49:17 PM" ID="6966578b-b326-4f16-a315-1b4228a9fa42">
<Step>
<Name>Send Email</Name>
<Success>1</Success>
<Message>Template Seleted and Filled</Message>
<Transaction Details="Email To: email@email.com Link: " IDTrans="243b0a3c-d8b7-49c3-b1d0-asdfsdsdfsdf"/>
</Step>
</Batch>.....
EDIT FINAL
Working Code, combination of all answers:
if (File.Exists(myXMLLog))
{
XDocument xmlDoc = XDocument.Load(myXMLLog);
XElement root = new XElement("Batch",
new XAttribute("ID", BatchID),
new XAttribute("Date", now),
new XElement("Step",
new XElement("Name", step),
new XElement("Success", success),
new XElement("Message", message),
new XElement("Transaction",
new XAttribute("IDTrans", transID),
new XAttribute("Details", details))));
xmlDoc.Root.Add(root);
xmlDoc.Save(myXMLLog);
}
else
{
using (XmlWriter writer = XmlWriter.Create(myXMLLog, settings))
{
writer.WriteStartDocument();
writer.WriteComment("This log was created by the Application.");
writer.WriteStartElement("Root");
writer.WriteStartElement("Batch");
writer.WriteAttributeString("ID", BatchID);
writer.WriteAttributeString("Date", now);
writer.WriteStartElement("Step");
writer.WriteElementString("Name", step);
writer.WriteElementString("Success", success);
writer.WriteElementString("Message", message);
writer.WriteStartElement("Transaction");
writer.WriteElementString("IDTrans", transID);
writer.WriteElementString("Details", details);
writer.WriteEndElement();
writer.Flush();
writer.WriteEndDocument();
}
}
I'm happy with the results. If anyone has suggestions on how to better format the XML, please do so. Thanks everyone.