Posted on 2006-09-11 11:13
Phono 阅读(1747)
评论(3) 编辑 收藏 所属分类:
.NET framework
最早接触xml配置文件驱动事件是在实习的时候,那时候恶毒的项目经理让我研究一个工作流引擎,鼎鼎大名的OSWORKFLOW,那东西是JAVA写的,唉~~太强人所难了....最后当然是可耻的失败鸟。
最近在研究业务架构的时候,偶尔发现了一个XML引擎驱动事件的程序,fm2.0的,倒不是为了报仇,只是我一直没弄明白到底xml配置是怎么驱动事件的。就看了看,多少有点收获,跟大家分享一下
工欲善其事,必先利其器,所以首先,要有个好的XML读写方法集,我看了看好多大家可能都用得上,就放在这了, 当个参考资料



Instance Data members#region Instance Data members

/**//// <summary>
/// File name to read from
/// </summary>
string m_sFilename = "";


/**//// <summary>
/// Rules engine to populate
/// </summary>
RulesEngine m_oRulesEngine;


/**//// <summary>
/// Namespace manager to use in XPath
/// </summary>
XmlNamespaceManager m_oNSMgr;


/**//// <summary>
/// Xml DOM document to use in reading
/// </summary>
XmlDocument m_oXmlDoc;
#endregion


Ctors#region Ctors

/**//// <summary>
/// Default Constructor
/// </summary>
public JaxlabReader()

{
m_oRulesEngine = new RulesEngine();
}


/**//// <summary>
/// Constructor that also specifies the XML file name.
/// </summary>
/// <remarks>
/// This constructor calls the LoadEngineByFileName method.
/// </remarks>
/// <param name="sFilename">the XML file location (including UNC or HTTP)</param>
public JaxlabReader(string sFilename)

{
m_oRulesEngine = new RulesEngine();
LoadEngineByFileName(sFilename);
}
#endregion


/**//// <summary>
/// Loads the
/// </summary>
/// <param name="sFilename">the XML file location (including UNC or HTTP)</param>
public void LoadEngineByFileName(string sFilename)

{
try

{
m_sFilename = sFilename;
XmlDocument oXmlDoc = new XmlDocument();
oXmlDoc.Load(m_sFilename);
LoadEngineByXmlDoc(oXmlDoc);
}
catch(Exception err)

{
System.Console.WriteLine(err.Message + "\n" + err.StackTrace);
}
}


/**//// <summary>
/// Loads the Rules Engine by in-memory XmlDocument.
/// </summary>
/// <param name="oXmlDoc">the in-memory XmlDocument</param>
public void LoadEngineByXmlDoc(XmlDocument oXmlDoc)

{
try

{
m_oXmlDoc = oXmlDoc;
m_oNSMgr = new XmlNamespaceManager(m_oXmlDoc.NameTable);

LoadXmlVariables(m_oXmlDoc.DocumentElement);

XmlNodeList oRuleNodeList = m_oXmlDoc.SelectNodes(".//Rules/Rule", m_oNSMgr);
for(int i = 0; i < oRuleNodeList.Count; i++)

{
XmlNode oXmlRule = oRuleNodeList[i];
LoadXMLRule(null, oXmlRule);
}

XmlNode oTriggersNode = m_oXmlDoc.SelectSingleNode("//Triggers", m_oNSMgr);
if(oTriggersNode != null)

{
LoadTrigger(oTriggersNode);
}
}
catch(Exception err)

{
System.Console.WriteLine(err.Message + "\n" + err.StackTrace);
}
}


/**//// <summary>
/// Loads an XML Node into the Rules Engine.
/// </summary>
/// <param name="oXmlRule">XmlNode of a RulesObject</param>
public void LoadXmlRule(XmlNode oXmlRule)

{
LoadXMLRule(null, oXmlRule);
}

private void LoadXmlVariables(XmlNode oXmlRoot)

{
XmlNodeList oXmlVars = oXmlRoot.SelectNodes(".//Variable");
for(int i = 0; i < oXmlVars.Count; i++)

{
XmlNode oXmlVar = oXmlVars[i];
string sVarID = oXmlVar.Attributes.GetNamedItem("id").Value;
string sValue = oXmlVar.InnerText;

Variable oVar = new Variable(sVarID, sValue);
m_oRulesEngine.AddVariable(oVar);
}
}

private void LoadXMLRule(RuleObject oParentRule, XmlNode oXmlRule)

{
string sID = oXmlRule.Attributes.GetNamedItem("id").Value;
XmlNode xmlAttrUse = oXmlRule.Attributes.GetNamedItem("useInferencing");
XmlNode oExpr = oXmlRule.SelectSingleNode("Expression", m_oNSMgr);

if(sID != "" && oExpr != null)

{
RuleObject oRule = new RuleObject(sID, oExpr.InnerText);
if(xmlAttrUse != null)

{
string sUse = xmlAttrUse.Value;
string sUseAdj = sUse.Trim().ToLower();
if(sUseAdj.CompareTo("true") == 0)

{
oRule.UseInferencing = true;
}
else

{
oRule.UseInferencing = false;
}
}

XmlNode oXmlActions = oXmlRule.SelectSingleNode("Actions", m_oNSMgr);
XmlNodeList oXmlActionList = oXmlActions.SelectNodes("./Action", m_oNSMgr);
for(int a = 0; a < oXmlActionList.Count; a++)

{
XmlNode oXmlAction = oXmlActionList[a];
Action oAction = MakeAction(oXmlAction);

oRule.AddAction(oAction);
}


XmlNode oXmlSubRules = oXmlRule.SelectSingleNode("SubRules", m_oNSMgr);
XmlNodeList oXmlSubRuleList = oXmlSubRules.SelectNodes("./Rule", m_oNSMgr);
for(int s = 0; s < oXmlSubRuleList.Count; s++)

{
XmlNode oXmlSubRule = oXmlSubRuleList[s];
LoadXMLRule(oRule, oXmlSubRule);
}

if(oParentRule != null)

{
oParentRule.AddSubRule(oRule);
}
else

{
this.m_oRulesEngine.Add(oRule);
}
}
}

private Action MakeAction(XmlNode oXmlAction)

{
XmlNode oMatch = oXmlAction.SelectSingleNode("Match", m_oNSMgr);
XmlNode oAssign = oXmlAction.SelectSingleNode("Assign", m_oNSMgr);

string sMatch = "";
string sAssign = "";

if(oMatch != null)

{
sMatch = oMatch.InnerText;
}
string sAssignType = "none";
if(oAssign != null)

{
XmlNode oAssignType = oAssign.Attributes.GetNamedItem("type");
if(oAssignType != null)

{
sAssignType = oAssignType.Value;
}
sAssign = oAssign.InnerText;
}

string sActionID = oXmlAction.Attributes.GetNamedItem("actionId").InnerText;
string sType = oXmlAction.Attributes.GetNamedItem("type").InnerText;

Action.ActionType oType = ParseActionType(sType);

Action oAction = new Action(sAssignType, sMatch, sAssign, oType, sActionID);
if(sAssignType.CompareTo("object") == 0)

{
XmlNode oXmlNodeAssign = oAssign.FirstChild;

XMLNodeWrapper oWrapped = new XMLNodeWrapper(oXmlNodeAssign);
oAction = new Action(sAssignType, sMatch, oWrapped, oType, sActionID);
}

return oAction;
}

private Action.ActionType ParseActionType(string sType)

{
if(sType.ToLower().CompareTo("var") == 0)

{
return Action.ActionType.Var;
}
else if(sType.ToLower().CompareTo("makevar") == 0)

{
return Action.ActionType.MakeVar;
}
else if(sType.ToLower().CompareTo("run") == 0)

{
return Action.ActionType.Run;
}
else if(sType.ToLower().CompareTo("stop") == 0)

{
return Action.ActionType.Stop;
}
else

{
return Action.ActionType.None;
}

}


Trigger Loading#region Trigger Loading
private void LoadTrigger(XmlNode oXmlNode)

{
XmlNodeList oXTriggers = oXmlNode.ChildNodes;
for(int i = 0; i < oXTriggers.Count; i++)

{
XmlNode oXTrigger = oXTriggers[i];
XmlNode oIDAttr = oXTrigger.Attributes.GetNamedItem("id");
XmlNode oVarIDAttr = oXTrigger.Attributes.GetNamedItem("varID");
XmlNode oRuleIDAttr = oXTrigger.Attributes.GetNamedItem("ruleID");

string sID = GetAttrValue(oIDAttr);
string sVarID = GetAttrValue(oVarIDAttr);
string sRuleID = GetAttrValue(oRuleIDAttr);

Trigger oTrigger = new Trigger(sID, sVarID, sRuleID);

this.m_oRulesEngine.AddTrigger(oTrigger);
}
}
#endregion

private string GetAttrValue(XmlNode oAttrNode)

{
if(oAttrNode != null)

{
return oAttrNode.Value;
}
else

![]()