Introduction
This article presents how to watch XML type data periodically. It is useful to watch real-time changing data (which is commonly seen in remote debugging or QA Tool).
XML represents tree-structured data efficiently, so XmlWatch uses TreeView to show the tree-structured data. It supports expand/shrink specific part of tree nodes easily using plus/minus icon.
Background
The idea of this program originated from GNU watch, which is used to watch specific program's output over time.
http://support.microsoft.com/kb/317597 was also helpful to put XML into TreeView.
How It Works (Briefly)
XmlWatch doesn't show all the XML attributes. It only shows node's name and value type data. but you can modify XmlWatch to see all the XML attributes.
XmlWatch doesn't need XML data to be well-formed, but the data should be valid XML document. Otherwise, XML Parser throws exception and GUI shows nothing.
- Time period is hard-coded in
Form1 UI Code. Currently timer is set to tick every second, so XML is retrieved every second.
- Only the changed part is highlighted if partial change occurred. and the highlighting would fade smoothly when it doesn't change more. User can see the difference easily.
Using the Code
ISubject and SimpleSubject is the interface class which provides XML data to UI class. A simple example below shows how to use this program. Only overriding Run() method is all you need to do. If you want to use callback-type implementation, you can use ISubject interface...
public class SimpleTest : SimpleSubject
{
private int count = 0;
public override XmlDocument Run()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<child>It is test</child><child2>" + count + "</child2>");
count += 1;
return doc;
}
}
... and all we need to do is bind that Subject class into UI. Currently it is done by static object Program.XmlSupplier which is used by UI periodically. You can modify the code below to set your own XML data:
public static ISubject XmlSupplier =
new SimpleTest();
One good use of XmlWatch is combining with boost::serialization. Because boost::serialization supports XML exporting, the user can make her/his big structured data into XML and watch it periodically using XmlWatch. Example code is shown below:
struct inner
{
int a,b,c;
};
struct outer
{
int aa,bb;
inner indata;
};
BOOST_SERIALIZATION_SPLIT_FREE(inner);
BOOST_SERIALIZATION_SPLIT_FREE(outer);
namespace boost { namespace serialization {
template<class>
void save(Archive &ar, const inner &data, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(data.a);
ar & BOOST_SERIALIZATION_NVP(data.b);
ar & BOOST_SERIALIZATION_NVP(data.c);
}
template<class>
void save(Archive &ar, const outer &data, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(data.aa);
ar & BOOST_SERIALIZATION_NVP(data.bb);
ar & BOOST_SERIALIZATION_NVP(data.indata);
}
}}
int main(void)
{
ofstream fout("output.xml");
boost::archive::xml_oarchive oa(fout, boost::archive::no_header);
outer data;
data.aa=1;
data.bb=3;
data.indata.a = data.indata.b = data.indata.c = 5;
oa << BOOST_SERIALIZATION_NVP(data);
}
Sample test C++ code is included in the source code. It needs boost library which can be downloaded here.
Points of Interest
Implementation of color animation is slow and flickering. I turned on double buffering, but it doesn't fix the issue when it shows over 200+ rows.
History
- 30th January, 2010: Initial post