Let's say I have an XML file such as this:
<root>
<level1 name="level1A">
<level2 name="level2A">
<level3 name="level3A">
<level4 name="level4A">
<level5 name="level5A">
<level6 name="level6A">
<level7 name="level7A">
<level8 name="level8A"></level8>
</level7>
</level6>
</level5>
</level4>
</level3>
</level2>
</level1>
<level1 name="level1B">
<level2 name="level2B">
<level3 name="level3B">
<level4 name="level4B">
<level5 name="level5B">
<level6 name="level6B">
<level7 name="level7B">
<level8 name="level8B"></level8>
</level7>
</level6>
</level5>
</level4>
</level3>
</level2>
</level1>
</root>
How can I read this file and execute a code snippet depending on the element? for example, if the "name" element says "level7a", execute code snippet X. If the name element says level7B, execute code snippet Y.
I can provide such code snippets if t makes answering the question easier. Thanks for the help!
You could create a Dictionary<string, Action>
which maps attribute names to actions. Then while parsing the xml you can look up the snippet in the dictionary and execute it.
Quick example:
var attributeActions = new Dictionary<string, Action>();
attributeActions["level1A"] = () => { /* do something */ };
attributeActions["level2A"] = () => { /* do something else */ };
...
// call it
attributActions[node.Attributes["name"]]();
You would need to check that the key actually exists but you could make extension method for that to encapsulate that functionality:
public static void Execute<TKey>(this IDictionary<TKey, Action> actionMap, TKey key)
{
Action action;
if (actionMap.TryGet(key, out action))
{
action();
}
}
Then you can call it like this:
attributActions.Execute(node.Attributes["name"]);
Instead of an Action
(which is a parameterless snippet returning void
) you might want to use Action<T>
or Func<T, R>
in case you need to pass paramters and/or get return values.
It seems you need 2 things:
going through the file (the Elements) in a specific order, I guess depth-first
execute an action based on a string value.
This should give you a rough idea:
var doc = System.Xml.Linq.XDocument.Load(fileName);
Visit(doc.Root);
private static void Visit(XElement element)
{
string name = element.Attribute("name").Value;
Execute(name);
// you seem to have just 1 child, this will handle multiple
// adjust to select only elements with a specific name
foreach (var child in element.Elements())
Visit(child);
}
private static void Execute(string name)
{
switch (name)
{
case "level1A" :
// snippet a
break;
// more cases
}
}
Credit for this idea goes to @ChrisWue. This is a different take that calls explicitly defined methods rather than anonymous ones:
private Dictionary<String, Action> actionList = new Dictionary<string, Action>();
private void method1() { }
private void method2() { }
private void buildActionList() {
actionList.Add("level7a", new Action(method1));
actionList.Add("level7B", new Action(method2));
// .. etc
}
public void processDoc() {
buildActionList();
foreach (XElement e in (XDocument.Parse(File.ReadAllText(@"C:\somefile.xml")).Elements())) {
string name = e.Attribute("name").Value;
if (name != null && actionList.ContainsKey(name)) {
actionList[name].Invoke();
}
}
}
.. obviously one would actually put something in the body of method1, method2, etc..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With