Oleg
Tue Jul 22 04:22:09 CDT 2003
Jon Skeet wrote:
>> I'm trying to write a log file (in XML) using XMLTextWriter. Each time
>>my application runs, certain events are logged and the same log file should
>>be updated.
>
>
> That can't be done without rewriting the whole file though - at least
> if you want the whole file to end up as one valid XML document. You'd
> need to read in the existing document, append child nodes to the root
> node, and then write out the whole document again. Basically XML
> doesn't work terribly nicely in this context, because any valid XML
> file which has anything (non-whitespace) added to it is no longer a
> valid XML file :(
I don't think it's so bad. XML does can be used as format for log files, but
in form of XML fragment. XML fragment is actually external general parsed
entity in XML specification terms - to be well-formed it must be incorporated
into well-formed XML document, but it's still useful on its own - one can
append elements to it (because it's XML fragment it can be non well-formed so
one can just append elements to the end of file, without necessity to parse
the whole fragment) and then read the whole log file by XmlTextReader, which
[thankfully to .NET developers] supports XML fragments (see "Reading XML
Fragments with the XmlTextReader" [1])
Here is small proof-of-concept example:
Writing to log:
class Test {
static void Main(string[] args) {
using (FileStream fs = File.Open("log.xml", FileMode.Append,
FileAccess.Write, FileShare.Read)) {
XmlTextWriter writer = new XmlTextWriter(fs, Encoding.ASCII);
for (int i=0; i<3; i++) {
writer.WriteElementString("item", "",
DateTime.Now.ToString());
writer.WriteWhitespace("\n");
}
writer.Close();
}
}
}
First run creates log.xml:
<item>7/22/2003 11:15:42 AM</item>
<item>7/22/2003 11:15:42 AM</item>
<item>7/22/2003 11:15:42 AM</item>
Second run appends three more items:
<item>7/22/2003 11:15:42 AM</item>
<item>7/22/2003 11:15:42 AM</item>
<item>7/22/2003 11:15:42 AM</item>
<item>7/22/2003 11:16:12 AM</item>
<item>7/22/2003 11:16:12 AM</item>
<item>7/22/2003 11:16:12 AM</item>
Reading log:
class Test {
static void Main(string[] args) {
using (FileStream fs = File.OpenRead("log.xml")) {
XmlParserContext context = new XmlParserContext(new
NameTable(), null,
null, XmlSpace.Default);
XmlTextReader reader = new XmlTextReader(fs,
XmlNodeType.Element, context);
while (reader.Read()) {
if (reader.NodeType == XmlNodeType.Element) {
Console.WriteLine("Element: {0}, Value: {1}",
reader.Name,
reader.ReadElementString());
}
}
}
}
}
And result is:
D:\projects\Test2\bin\Debug>Test2.exe
Element: item, Value: 7/22/2003 11:15:42 AM
Element: item, Value: 7/22/2003 11:15:42 AM
Element: item, Value: 7/22/2003 11:15:42 AM
Element: item, Value: 7/22/2003 11:16:12 AM
Element: item, Value: 7/22/2003 11:16:12 AM
Element: item, Value: 7/22/2003 11:16:12 AM
[1]
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconreadingxmlfragmentswithxmltextreader.asp
--
Oleg Tkachenko
http://www.tkachenko.com/blog
Multiconn Technologies, Israel