/// <summary> /// Performs validation on the xml source as well as evaluates conditional and flow expresions /// </summary> /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> /// <param name="reader"></param> /// <returns>the output xml </returns> public string Process(XmlReader reader) { if(reader == null) { throw new ArgumentException("Invalid XML reader to pre-process"); } IfContext context = new IfContext(true, true, IfState.None); StringWriter xmlText = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(xmlText); writer.Formatting = Formatting.Indented; while(reader.Read()) { if(reader.NodeType == XmlNodeType.ProcessingInstruction) { bool ignore = false; switch(reader.LocalName) { case "if": m_IfStack.Push(context); context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); ignore = true; break; case "elseif": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } else if(context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } context.State = IfState.ElseIf; if(!context.EverKept) { context.Keep = ParseExpression(reader.Value); } else { context.Keep = false; } ignore = true; break; case "else": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'else' outside of 'if'"); } else if(context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'else' outside of 'if'"); } context.State = IfState.Else; context.Keep = !context.EverKept; ignore = true; break; case "endif": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'endif' outside of 'if'"); } context = (IfContext)m_IfStack.Pop(); ignore = true; break; } if(ignore) { continue; } }//end pre-proc instruction if(!context.Active || !context.Keep) { continue; } switch(reader.NodeType) { case XmlNodeType.Element: bool empty = reader.IsEmptyElement; writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) { writer.WriteAttributeString(reader.Name, reader.Value); } if(empty) { writer.WriteEndElement(); } break; case XmlNodeType.EndElement: writer.WriteEndElement(); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.CDATA: writer.WriteCData(reader.Value); break; default: break; } } if(m_IfStack.Count != 0) { throw new WarningException("Mismatched 'if', 'endif' pair"); } return xmlText.ToString(); }
/// <summary> /// Performs validation on the xml source as well as evaluates conditional and flow expresions /// </summary> /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> /// <param name="initialReader"></param> /// <returns>the output xml </returns> public string Process(XmlReader initialReader) { if (initialReader == null) { throw new ArgumentException("Invalid XML reader to pre-process"); } IfContext context = new IfContext(true, true, IfState.None); StringWriter xmlText = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(xmlText); writer.Formatting = Formatting.Indented; // Create a queue of XML readers and add the initial // reader to it. Then we process until we run out of // readers which lets the <?include?> operation add more // readers to generate a multi-file parser and not require // XML fragments that a recursive version would use. Stack <XmlReader> readerStack = new Stack <XmlReader>(); readerStack.Push(initialReader); while (readerStack.Count > 0) { // Pop off the next reader. XmlReader reader = readerStack.Pop(); // Process through this XML reader until it is // completed (or it is replaced by the include // operation). while (reader.Read()) { // The prebuild file has a series of processing // instructions which allow for specific // inclusions based on operating system or to // include additional files. if (reader.NodeType == XmlNodeType.ProcessingInstruction) { bool ignore = false; switch (reader.LocalName) { case "include": // use regular expressions to parse out the attributes. MatchCollection matches = includeFileRegex.Matches(reader.Value); // make sure there is only one file attribute. if (matches.Count > 1) { throw new WarningException("An <?include ?> node was found, but it specified more than one file."); } if (matches.Count == 0) { throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); } // ***** Adding for wildcard handling // Push current reader back onto the stack. readerStack.Push(reader); // Pull the file out from the regex and make sure it is a valid file before using it. string filename = matches[0].Groups[1].Value; filename = String.Join(Path.DirectorySeparatorChar.ToString(), filename.Split(new char[] { '/', '\\' })); if (!filename.Contains("*")) { FileInfo includeFile = new FileInfo(filename); if (!includeFile.Exists) { throw new WarningException("Cannot include file: " + includeFile.FullName); } // Create a new reader object for this file. Then put the old reader back on the stack and start // processing using this new XML reader. XmlReader newReader = new XmlTextReader(includeFile.Open(FileMode.Open, FileAccess.Read, FileShare.Read)); reader = newReader; readerStack.Push(reader); } else { WildCardInclude(readerStack, filename); } reader = (XmlReader)readerStack.Pop(); ignore = true; break; case "if": m_IfStack.Push(context); context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); ignore = true; break; case "elseif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } context.State = IfState.ElseIf; if (!context.EverKept) { context.Keep = ParseExpression(reader.Value); } else { context.Keep = false; } ignore = true; break; case "else": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'else' outside of 'if'"); } if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'else' outside of 'if'"); } context.State = IfState.Else; context.Keep = !context.EverKept; ignore = true; break; case "endif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'endif' outside of 'if'"); } context = m_IfStack.Pop(); ignore = true; break; } if (ignore) { continue; } } //end pre-proc instruction if (!context.Active || !context.Keep) { continue; } switch (reader.NodeType) { case XmlNodeType.Element: bool empty = reader.IsEmptyElement; writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) { writer.WriteAttributeString(reader.Name, reader.Value); } if (empty) { writer.WriteEndElement(); } break; case XmlNodeType.EndElement: writer.WriteEndElement(); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.CDATA: writer.WriteCData(reader.Value); break; default: break; } } if (m_IfStack.Count != 0) { throw new WarningException("Mismatched 'if', 'endif' pair"); } } return(xmlText.ToString()); }
/// <summary> /// Performs validation on the xml source as well as evaluates conditional and flow expresions /// </summary> /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> /// <param name="initialReader"></param> /// <returns>the output xml </returns> public string Process(XmlReader initialReader) { if(initialReader == null) { throw new ArgumentException("Invalid XML reader to pre-process"); } IfContext context = new IfContext(true, true, IfState.None); StringWriter xmlText = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(xmlText); writer.Formatting = Formatting.Indented; // Create a queue of XML readers and add the initial // reader to it. Then we process until we run out of // readers which lets the <?include?> operation add more // readers to generate a multi-file parser and not require // XML fragments that a recursive version would use. Stack<XmlReader> readerStack = new Stack<XmlReader>(); readerStack.Push(initialReader); while(readerStack.Count > 0) { // Pop off the next reader. XmlReader reader = readerStack.Pop(); // Process through this XML reader until it is // completed (or it is replaced by the include // operation). while(reader.Read()) { // The prebuild file has a series of processing // instructions which allow for specific // inclusions based on operating system or to // include additional files. if(reader.NodeType == XmlNodeType.ProcessingInstruction) { bool ignore = false; switch(reader.LocalName) { case "include": // use regular expressions to parse out the attributes. MatchCollection matches = includeFileRegex.Matches(reader.Value); // make sure there is only one file attribute. if(matches.Count > 1) { throw new WarningException("An <?include ?> node was found, but it specified more than one file."); } if(matches.Count == 0) { throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); } // ***** Adding for wildcard handling // Push current reader back onto the stack. readerStack.Push (reader); // Pull the file out from the regex and make sure it is a valid file before using it. string filename = matches[0].Groups[1].Value; filename = String.Join (Path.DirectorySeparatorChar.ToString (), filename.Split (new char[] { '/', '\\' })); if (!filename.Contains ("*")) { FileInfo includeFile = new FileInfo (filename); if (!includeFile.Exists) { throw new WarningException ("Cannot include file: " + includeFile.FullName); } // Create a new reader object for this file. Then put the old reader back on the stack and start // processing using this new XML reader. XmlReader newReader = new XmlTextReader (includeFile.Open (FileMode.Open, FileAccess.Read, FileShare.Read)); reader = newReader; readerStack.Push (reader); } else { WildCardInclude (readerStack, filename); } reader = (XmlReader)readerStack.Pop (); ignore = true; break; case "if": m_IfStack.Push(context); context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); ignore = true; break; case "elseif": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } if(context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } context.State = IfState.ElseIf; if(!context.EverKept) { context.Keep = ParseExpression(reader.Value); } else { context.Keep = false; } ignore = true; break; case "else": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'else' outside of 'if'"); } if(context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'else' outside of 'if'"); } context.State = IfState.Else; context.Keep = !context.EverKept; ignore = true; break; case "endif": if(m_IfStack.Count == 0) { throw new WarningException("Unexpected 'endif' outside of 'if'"); } context = m_IfStack.Pop(); ignore = true; break; } if(ignore) { continue; } }//end pre-proc instruction if(!context.Active || !context.Keep) { continue; } switch(reader.NodeType) { case XmlNodeType.Element: bool empty = reader.IsEmptyElement; writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) { writer.WriteAttributeString(reader.Name, reader.Value); } if(empty) { writer.WriteEndElement(); } break; case XmlNodeType.EndElement: writer.WriteEndElement(); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.CDATA: writer.WriteCData(reader.Value); break; default: break; } } if(m_IfStack.Count != 0) { throw new WarningException("Mismatched 'if', 'endif' pair"); } } return xmlText.ToString(); }
/// <summary> /// Performs validation on the xml source as well as evaluates conditional and flow expresions /// </summary> /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> /// <param name="reader"></param> /// <returns>the output xml </returns> public string Process(XmlReader reader) { if (reader == null) { throw new ArgumentException("Invalid XML reader to pre-process"); } IfContext context = new IfContext(true, true, IfState.None); StringWriter xmlText = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(xmlText); writer.Formatting = Formatting.Indented; while (reader.Read()) { if (reader.NodeType == XmlNodeType.ProcessingInstruction) { bool ignore = false; switch (reader.LocalName) { case "if": m_IfStack.Push(context); context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); ignore = true; break; case "elseif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } else if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } context.State = IfState.ElseIf; if (!context.EverKept) { context.Keep = ParseExpression(reader.Value); } else { context.Keep = false; } ignore = true; break; case "else": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'else' outside of 'if'"); } else if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'else' outside of 'if'"); } context.State = IfState.Else; context.Keep = !context.EverKept; ignore = true; break; case "endif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'endif' outside of 'if'"); } context = (IfContext)m_IfStack.Pop(); ignore = true; break; } if (ignore) { continue; } } //end pre-proc instruction if (!context.Active || !context.Keep) { continue; } switch (reader.NodeType) { case XmlNodeType.Element: bool empty = reader.IsEmptyElement; writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) { writer.WriteAttributeString(reader.Name, reader.Value); } if (empty) { writer.WriteEndElement(); } break; case XmlNodeType.EndElement: writer.WriteEndElement(); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.CDATA: writer.WriteCData(reader.Value); break; default: break; } } if (m_IfStack.Count != 0) { throw new WarningException("Mismatched 'if', 'endif' pair"); } return(xmlText.ToString()); }
/// <summary> /// Performs validation on the xml source as well as evaluates conditional and flow expresions /// </summary> /// <exception cref="ArgumentException">For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml</exception> /// <param name="reader"></param> /// <returns>the output xml </returns> public string Process(XmlReader inputReader) { if (inputReader == null) { throw new ArgumentException("Invalid XML reader to pre-process"); } Stack xmlReaderStack = new Stack(); IfContext context = new IfContext(true, true, IfState.None); StringWriter xmlText = new StringWriter(); XmlTextWriter writer = new XmlTextWriter(xmlText); writer.Formatting = Formatting.Indented; XmlReader reader; xmlReaderStack.Push(inputReader); while (xmlReaderStack.Count > 0) { reader = (XmlReader)xmlReaderStack.Pop(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.ProcessingInstruction) { bool ignore = false; switch (reader.LocalName) { case "include": string filename = null; // use regular expressions to parse out the attributes. Regex regex = new Regex(@"file=""(.*)"""); MatchCollection matches = regex.Matches(reader.Value); // make sure there is only one file attribute. if (matches.Count > 1) { throw new WarningException("An <?include ?> node was found, but it specified more than one file."); } else if (matches.Count == 0) { throw new WarningException("An <?include ?> node was found, but it did not specify the file attribute."); } // pull out the group inside the parentheses in the regex. // this will be the actual filename specified filename = matches[0].Groups[1].Value; XmlReader newReader = new XmlTextReader( File.Open(filename, FileMode.Open)); xmlReaderStack.Push(reader); reader = newReader; ignore = true; break; case "if": m_IfStack.Push(context); context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); ignore = true; break; case "elseif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } else if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'elseif' outside of 'if'"); } context.State = IfState.ElseIf; if (!context.EverKept) { context.Keep = ParseExpression(reader.Value); } else { context.Keep = false; } ignore = true; break; case "else": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'else' outside of 'if'"); } else if (context.State != IfState.If && context.State != IfState.ElseIf) { throw new WarningException("Unexpected 'else' outside of 'if'"); } context.State = IfState.Else; context.Keep = !context.EverKept; ignore = true; break; case "endif": if (m_IfStack.Count == 0) { throw new WarningException("Unexpected 'endif' outside of 'if'"); } context = (IfContext)m_IfStack.Pop(); ignore = true; break; } if (ignore) { continue; } } //end pre-proc instruction if (!context.Active || !context.Keep) { continue; } switch (reader.NodeType) { case XmlNodeType.Element: bool empty = reader.IsEmptyElement; writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) { writer.WriteAttributeString(reader.Name, reader.Value); } if (empty) { writer.WriteEndElement(); } break; case XmlNodeType.EndElement: writer.WriteEndElement(); break; case XmlNodeType.Text: writer.WriteString(reader.Value); break; case XmlNodeType.CDATA: writer.WriteCData(reader.Value); break; default: break; } } } if (m_IfStack.Count != 0) { throw new WarningException("Mismatched 'if', 'endif' pair"); } return(xmlText.ToString()); }