Reputation: 81
I am using WinForms. I have an XML document that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<MarcusXMLFile xmlns:Responses="http://www.rewardstrike.com/XMLFile1.xml">
<response>
<greatmood>
<yes>
<replytocommand>
<answer>Yes.</answer>
<answer>Yes, sir.</answer>
<answer>Settings.Default.User</answer>
</replytocommand>
</yes>
</greatmood>
</response>
</MarcusXMLFile>
To read this xml document, I use:
private void Responses()
{
string query = String.Format("http://www.rewardstrike.com/XMLFile1.xml");
XmlDocument Responses = new XmlDocument();
Responses.Load(query);
XmlNode channel = Responses.SelectSingleNode("MarcusXMLFile");
if (QEvent == "yesreplytocommand")
{
XmlNodeList yesreplytocommand = Responses.SelectNodes("MarcusXMLFile/response/greatmood/yes/replytocommand/answer");
foreach (XmlNode ans in yesreplytocommand
.Cast<XmlNode>()
.OrderBy(elem => Guid.NewGuid()))
{
response = ans.InnerText;
}
}
}
and then to display:
QEvent = "yesreplytocommand";
Responses();
Console.WriteLine(response);
My problem is when it gets Settings.Default.User and displays it, I want it to display it as c# code so that it actually gets the value from the application. Right now it is actually displaying "Settings.Default.User". How do I do this?
Upvotes: 1
Views: 134
Reputation: 17855
First, you'll need a way to recognize which of your entries are literals and which are expressions. You could do it by adding an attribute to the XML node:
<?xml version="1.0" encoding="utf-8" ?>
<MarcusXMLFile xmlns:Responses="http://www.rewardstrike.com/XMLFile1.xml">
<response>
<greatmood>
<yes>
<replytocommand>
<answer>Yes.</answer>
<answer>Yes, sir.</answer>
<answer expression="true">DefaultSettings.User</answer>
</replytocommand>
</yes>
</greatmood>
</response>
</MarcusXMLFile>
Based on that you can modify your parsing code to either directly use the value from XML or evaluate it instead:
foreach (XmlNode ans in yesreplytocommand
.Cast<XmlNode>()
.OrderBy(elem => Guid.NewGuid()))
{
var attribute = ans.Attributes["expression"];
if (attribute != null && attribute.Value == "true")
{
Console.WriteLine(Evaluate(ans.InnerText));
}
else
{
Console.WriteLine(ans.InnerText);
}
}
There's still the problem of evaluating that expression. There's no easy built-in way to do that from C#. But you could use Dynamic Expresso. This is how Evaluate
method could look like:
public string Evaluate(string expression)
{
var interpreter = new Interpreter();
interpreter.SetVariable("DefaultSettings", Settings.Default);
return interpreter.Eval<string>(expression);
}
As you can see, you'll still have to define the expression variables yourself. For the above to work, you will have to use DefaultSettings.User
in your XML instead of Settings.Default.User
. I already made that change in my sample XML at the beginning of the answer.
Upvotes: 3
Reputation: 651
You should take a look at XML Serialization.
Really basic on how it works is that it can convert a struct or a class like this:
struct Foo
{
int bar = 0;
Vector2 obj = new Vector2(10, 50);
}
into this:
<?xml version="1.0" ?>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"">
<bar>0</bar>
<obj>
<X>10</X>
<Y>50</Y>
</ojb>
</Foo>
And the other way around.
The methods used to load and save code looks like this:
public static void Save(string filepath, Foo foobject)
{
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
using (Stream stream = File.OpenWrite(filepath))
{
serializer.Serialize(stream, foobject);
}
}
public static Foo Load(string filepath)
{
Foo myFoo;
XmlSerializer serializer = new XmlSerializer(typeof(Foo));
using (Stream stream = File.OpenRead(filepath))
{
myFoo = (Foo)serializer.Deserialize(stream);
}
}
It converts xml code to c# code, and other way around. It cannot convert methods, but it can convert most properties and classes.
Upvotes: 0