将新行添加到XML文件

时间:2014-01-23 02:40:44

标签: c# xml linq-to-xml xmlwriter

我有一个创建XML日志的程序。首先,我检查XML是否存在,如果不存在,我使用以下代码创建它:

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 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>

所以第二次,它检查XML是否存在,它确实存在,所以不应该只是添加它。我正在使用以下代码:

                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);

所以现在我希望XML文件看起来像这样:

  
<!--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>

但我得到了一个例外“重复属性”。

我做错了什么?

谢谢!

修改

XML文档确实有它的顶部。有效的XML会非常好,但不是最好的。

编辑编辑:

这就是我的代码现在的样子:

            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();
                }
            }

我对XML的格式没问题,我现在的问题是在第一个BATCH中进行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>.....

编辑最终

工作代码,所有答案的组合:

            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();
                }
            }

我对结果感到满意。如果有人对如何更好地格式化XML有任何建议,请这样做。谢谢大家。

3 个答案:

答案 0 :(得分:3)

您当前的代码会将所有这些元素和属性添加到root,而不是向新创建的元素添加一些属性。

元素创建应如下所示:

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 XElement("ID", transID),
            new XElement("Details", details))));

答案 1 :(得分:2)

您正尝试将两个ID属性添加到同一个Batch元素。

   root.Add(new XAttribute("ID", BatchID));
   root.Add(new XAttribute("ID", transID));

我猜您需要在ID元素中添加DetailsTransaction元素,所以在添加Transaction元素时请执行以下操作:

root.Add(new XElement("Transaction",
             new XElement("ID", transID),
             new XElement("Details",details));

您也可以在一个声明中完成所有这些:

XElement root = new XElement("Batch",
            new XAttribute("ID", BatchID),
            new XAttribute("Date", now),
            new XElement("Step",
                new XElement("Success", success),
                new XElement("Message", message),
                new XElement("Transaction",
                    new XElement("ID", transID),
                    new XElement("Details", details))));

注意:正如MarcinJuraszek提到他的答案,你将所有属性直接添加到你的根元素。例如:

root.Add(new XElement("Step"));
root.Add(new XAttribute("Name", step));
root.Add(new XAttribute("Success", success));

该代码未向您的Name元素添加SuccessStep属性,它会将这两个属性添加到您的根元素。要修复此问题,您需要将这些属性添加到您的Step元素在创建时:

XElement stepElement = new XElement("Step",
                           new XAttribute("Name", step),
                           new XAttribute("Success", success));

然后您可以将此元素添加到根目录:

root.Add(stepElement);

最后请注意,您应该使用XElement添加新元素,根据您的XML文档,Name,Success,Message,Id (transaction)Details应为XElement而不是XAttribute.

答案 2 :(得分:1)

首先,您有两个“ID”属性,请删除其中任何一个:

root.Add(new XAttribute("ID", BatchID));
……………………
root.Add(new XAttribute("ID", transID));

然后你不能这样做,因为你的xml没有头根。我的意思是你应该通过添加一个“Root”作为xml的根头来改变你的xml文件

<!--This log was created by the BaswareVendorRegistrationCA Application.-->
<Root>
  <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>
</Root>

然后添加:

 XDocument xmlDoc = XDocument.Load("XMLFile1.xml");
            XElement root = new XElement("Batch");

            root.Add(new XAttribute("ID", 1));
            root.Add(new XAttribute("Date", 2));
            root.Add(new XElement("Step"));
            root.Add(new XAttribute("Name", 3));
            root.Add(new XAttribute("Success", 4));
            root.Add(new XAttribute("Message", 5));
            root.Add(new XElement("Transaction"));
            root.Add(new XAttribute("Details", 7));

            xmlDoc.Root.Add(root);
            xmlDoc.Save("c:\\try.xml");

PS:如果您的xml没有根元素,VS会告诉您这是一个无效的xml:

enter image description here