How to store and parse story actions in XML

How to store and parse story actions in XML

I been working on a game in Unity that reads its story (Actions, scene descriptions, NPC's, ect...) from an XML and have been wondering there was a better way to store actions based on player data such as item in an inventory or attribute.
An example would be the player having a light source greater then 5 on hand while entering a dark room.

 You enter a dark room 
  and do not have enough light to see it well.

How would I be able to act on the above logic in C# without hard coding the actions and load dynamically from the XML? Also how should I handle logic in XML if it requires multiple actions or parameters?
For example having a crowbar and the strength greater then 15 to open a door.

 You see a stuck door in front of you.
  Your effort to remove the door has failed.

Because I am rather new to parsing XML I can't think of a way to break the logic out of the XML and use it in code dynamically. I looked over and really did not seem to answer my question on how to solve it in C#.
Spent more time on this and with Blue's answer I was able to come up with a viable solution.
Sample XML
  You enter a dark room 
   and do you do not have a light source.


Answer 1:

I would look heavily into state machines and deserializing the XML data into state instances.

You can create class definition for a condition, be that an integer on an item for it’s int brightness = 4; value or a string name = "torch"; in the inventory.

Something along these lines:

public enum ConditionType{

abstract class Condition{

    abstract ConditionType type;
    string failMessage = "Condition not met";

    public abstract bool IsThisConditionMet();


//example concrete condition
class ItemLevelCondition : Condition{

    Condition type = itemLevelReq;
    string itemType;
    int levelReq;

    public ItemLevelCondition(String item, int level, string fail){
        this.itemType = item;
        this.levelReq = level;
        this.failMessage = fail;

    public bool IsThisConditionMet(){
            return player.items[itemType].level >= this.levelReq;
        } else {
            return false;


class Scene{
     string description;
     Condition[] requirements;

     public Scene(string description,Condition[] requirements)
         this.description = description;
         this.requirements = requirements;

     public bool AreAllConditionsMet(){
         bool result = true;
         string responseMessage;
         foreach(Condition condition in requirements){
                 responseMessage += condition.failMessage + "\n";
             result &= condition.IsThisConditionMet();

         return result;

     public void OutputFailMessage(){

Please excuse the roughness but I hope this gives you a decent idea for structure.
Formatting your XML a little better you can then create a parser to create the scenes and the requirements in them, here is an example of both the scenes above in one:

<scene index="5">
 <description>You enter a dark room and feel a door stuck in front of you</description>
 <condition type="itemLevelReq" itemType="light" levelReq="5">
  <failMessage>and do not have enough light to see it well.</text>
 <condition type="playerAttribute" attrType="strength" levelReq="15">
  <failMessage>You are not strong enough.</text>
 <condition type="itemEquip" itemType="crowbar" equipped="true">
  <failMessage>You do not have a crowbar equipped.</text>

Here is a snippet of how to do the XML parsing itself:

using System.Collections.Generic;
using System.Xml;
    public static List<Scene> InitialiseScenes()
        List<Scene> scenes = new List<Scene>();

        Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Scenes.xml");

        //This if block verifies the file was loaded into the stream and throws a FileNotFound if it isn't
        if (stream != null)
            StreamReader reader = new StreamReader(stream);

            XmlDocument sceneDoc = new XmlDocument();

            string xpathQuery = "/scenes/scene";
            foreach (XmlNode sceneNode in sceneDoc.SelectNodes(xpathQuery))
                //Set up new Champion details
                Scene currentScene;
                List<Condition> conditions = InitialiseConditions(sceneNode.SelectNodes("conditions"));

                currentScene = new Scene(sceneNode.SelectNode("description").InnerText, conditions)

            throw new FileNotFoundException("The resource file for the champions data is missing.", "Champions.xml");
        return champions;

    public List<Condition> InitialiseConditions(XmlNodeList nodeList) { 

        //Get conditions from nodes
        List<Condition> result;
        foreach (XmlNode conditionNode in nodeList){
            Condition tmpCondition;

            //TODO: Create list of nodes and use switch statement to load the
            // node into a concrete implementation of the abstract Condition class
            //eg. tmpCondition = new ItemLevelCondition(item, level, fail);


I hope this gets you on the right track.