我将日志存储在xml文件中......
在传统的直接文本格式方法中,通常只有openFile ...然后是writeLine方法...
如何将新条目添加到xml文档结构中,就像使用文本文件方法一样?
答案 0 :(得分:4)
使用XmlWriter。
示例代码:
public class Quote
{
public string symbol;
public double price;
public double change;
public int volume;
}
public void Run()
{
Quote q = new Quote
{
symbol = "fff",
price = 19.86,
change = 1.23,
volume = 190393,
};
WriteDocument(q);
}
public void WriteDocument(Quote q)
{
var settings = new System.Xml.XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent= true
};
using (XmlWriter writer = XmlWriter.Create(Console.Out, settings))
{
writer.WriteStartElement("Stock");
writer.WriteAttributeString("Symbol", q.symbol);
writer.WriteElementString("Price", XmlConvert.ToString(q.price));
writer.WriteElementString("Change", XmlConvert.ToString(q.change));
writer.WriteElementString("Volume", XmlConvert.ToString(q.volume));
writer.WriteEndElement();
}
}
示例输出:
<Stock Symbol="fff">
<Price>19.86</Price>
<Change>1.23</Change>
<Volume>190393</Volume>
</Stock>
见 Writing with an XmlWriter 了解更多信息。
答案 1 :(得分:1)
最大的区别在于您考虑日志数据的方式。在纯文本文件中,您确实只是添加新行。然而,XML是一种树结构,你需要这样思考。您要添加的内容可能是另一个NODE,即:
<log>
<time>12:30:03 PST</time>
<user>joe</user>
<action>login</action>
<log>
因为它是一棵树,你需要问的是你在哪个父节点上添加这个新节点。这通常都在您的DTD中定义(Aka,您如何定义数据结构)。希望这比使用什么库更有帮助,因为一旦理解了这个原则,库的界面应该更有意义。
答案 2 :(得分:1)
为什么重新发明轮子?将TraceSource Class (System.Diagnostics)与XmlWriterTraceListener一起使用。
答案 3 :(得分:1)
以XML格式编写日志文件的一个问题是,您不能只将行附加到文件的末尾,因为最后一行必须有一个关闭的根元素(使XML有效)
一个好的解决方案是使用XML-include的东西将两个XML文件链接在一起:
标题文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log [
<!ENTITY loglines SYSTEM "loglines.xml">
]>
<log>
&loglines;
</log>
行文件(在此示例中,名为loglines.xml):
<logline date="2007-07-01 13:56:04.313" text="start process" />
<logline date="2007-07-01 13:56:25.837" text="do something" />
<logline date="2007-07-01 13:56:25.853" text="the end" />
然后,您可以在“行文件”中添加新行,但(大多数)XML解析器将能够打开头文件并正确读取行。
Filip指出:地球上的每个XML解析器都无法正确解析此XML。但我使用过的所有解析器都是正确的。
答案 4 :(得分:1)
很抱歉发布旧帖子的答案。我很久以前就开发了同样的东西。在这里,我想在日期的xml文件中分享我的记录器保存日志数据的完整代码。
using System.IO;
using System.Xml;
using System.Threading;
public class BBALogger
{
public enum MsgType
{
Error ,
Info
}
public static BBALogger Instance
{
get
{
if (_Instance == null)
{
lock (_SyncRoot)
{
if (_Instance == null)
_Instance = new BBALogger();
}
}
return _Instance;
}
}
private static BBALogger _Instance;
private static object _SyncRoot = new Object();
private static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
private BBALogger()
{
LogFileName = DateTime.Now.ToString("dd-MM-yyyy");
LogFileExtension = ".xml";
LogPath= Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\\Log";
}
public StreamWriter Writer { get; set; }
public string LogPath { get; set; }
public string LogFileName { get; set; }
public string LogFileExtension { get; set; }
public string LogFile { get { return LogFileName + LogFileExtension; } }
public string LogFullPath { get { return Path.Combine(LogPath, LogFile); } }
public bool LogExists { get { return File.Exists(LogFullPath); } }
public void WriteToLog(String inLogMessage, MsgType msgtype)
{
_readWriteLock.EnterWriteLock();
try
{
LogFileName = DateTime.Now.ToString("dd-MM-yyyy");
if (!Directory.Exists(LogPath))
{
Directory.CreateDirectory(LogPath);
}
var settings = new System.Xml.XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true
};
StringBuilder sbuilder = new StringBuilder();
using (StringWriter sw = new StringWriter(sbuilder))
{
using (XmlWriter w = XmlWriter.Create(sw, settings))
{
w.WriteStartElement("LogInfo");
w.WriteElementString("Time", DateTime.Now.ToString());
if (msgtype == MsgType.Error)
w.WriteElementString("Error", inLogMessage);
else if (msgtype == MsgType.Info)
w.WriteElementString("Info", inLogMessage);
w.WriteEndElement();
}
}
using (StreamWriter Writer = new StreamWriter(LogFullPath, true, Encoding.UTF8))
{
Writer.WriteLine(sbuilder.ToString());
}
}
catch (Exception ex)
{
}
finally
{
_readWriteLock.ExitWriteLock();
}
}
public static void Write(String inLogMessage, MsgType msgtype)
{
Instance.WriteToLog(inLogMessage, msgtype);
}
}
BBALogger.Write("pp1", BBALogger.MsgType.Error);
BBALogger.Write("pp2", BBALogger.MsgType.Error);
BBALogger.Write("pp3", BBALogger.MsgType.Info);
MessageBox.Show("done");
我的代码可以帮助您和其他人:)
答案 5 :(得分:0)
如果没有关于你正在做什么的更多信息,我只能提供一些基本建议来尝试。
大多数名为“AppendChild”的XML对象都有一种方法。您可以使用此方法添加您创建的新节点,其中包含日志注释。此节点将显示在项目列表的末尾。您将使用所有日志节点所在的父元素作为要调用的对象。
希望有所帮助。
答案 6 :(得分:0)
XML需要一个文档元素(基本上是顶级标记开始和结束文档)。 这意味着格式良好的XML文档需要具有开头和结尾,这听起来不太适合日志,其中日志的当前“结束”不断扩展。
除非您编写批量自包含日志,并在短时间内编写要记录到一个文件的所有内容,否则我会考虑使用XML以外的其他内容。
如果您正在编写已完成工作单元的日志,或者在整个工作完成之前不需要检查的日志,您可以使用您的方法 - 只需打开文件,写入日志行,关闭工作单位完成后的文件。
答案 7 :(得分:0)
要编辑xml文件,您还可以使用LINQ。你可以看看这里的方式: http://www.linqhelp.com/linq-tutorials/adding-to-xml-file-using-linq-and-c/