/// <summary> /// Compile a set of actions to perform. /// </summary> /// <remarks> /// <para> /// This method will parse the child <see cref="XmlElement"/>s of <paramref name="containingNode"/>. /// Based on the name of the element, the the compiler will look for an <see cref="XmlActionCompilerOperatorExtensionPoint{TActionContext, TSchemaContext}"/> /// extension that handles the element type. A list is constructed of all actions to perform, and a class implementing the /// <see cref="IActionSet{T}"/> interface is returned which can be called to exectute the actions based on input data. /// </para> /// </remarks> /// <param name="containingNode">The input XML containg actions to perform.</param> /// <param name="schemaContext"></param> /// <param name="checkSchema">Check the schema when compiling.</param> /// <returns>A class instance that implements the <see cref="IActionSet{T}"/> interface.</returns> public IActionSet <TActionContext> Compile(XmlElement containingNode, TSchemaContext schemaContext, bool checkSchema) { // Note, recursive calls are made to this method to compile. The schema is not // checked on recursive calls, but should be checked once on an initial compile. if (checkSchema) { // We must parse the XML to get the schema validation to work. So, we write // the xml out to a string, and read it back in with Schema Validation enabled StringWriter sw = new StringWriter(); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); xmlWriterSettings.Encoding = Encoding.UTF8; xmlWriterSettings.ConformanceLevel = ConformanceLevel.Fragment; xmlWriterSettings.Indent = false; xmlWriterSettings.NewLineOnAttributes = false; xmlWriterSettings.IndentChars = ""; XmlWriter xmlWriter = XmlWriter.Create(sw, xmlWriterSettings); foreach (XmlNode node in containingNode.ChildNodes) { node.WriteTo(xmlWriter); } xmlWriter.Close(); XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); xmlReaderSettings.Schemas = new XmlSchemaSet(); if (!_schemas.ContainsKey(schemaContext)) { _schemas.Add(schemaContext, CreateSchema(schemaContext)); } xmlReaderSettings.Schemas.Add(_schemas[schemaContext]); xmlReaderSettings.ValidationType = ValidationType.Schema; xmlReaderSettings.ConformanceLevel = ConformanceLevel.Fragment; XmlReader xmlReader = XmlTextReader.Create(new StringReader(sw.ToString()), xmlReaderSettings); while (xmlReader.Read()) { ; } xmlReader.Close(); } List <IActionItem <TActionContext> > actions = new List <IActionItem <TActionContext> >(); ICollection <XmlNode> nodes = GetChildElements(containingNode); foreach (XmlNode node in nodes) { if (_operatorMap.ContainsKey(node.Name)) { IXmlActionCompilerOperator <TActionContext, TSchemaContext> op = _operatorMap[node.Name]; actions.Add(op.Compile(node as XmlElement)); } else { throw new XmlActionCompilerException(string.Format(SR.FormatUnableToFindMatchingAction, node.Name)); } } return(new ActionSet <TActionContext>(actions)); }
private void AddOperator(IXmlActionCompilerOperator <TActionContext, TSchemaContext> op) { _operatorMap.Add(op.OperatorTag, op); }