using System; using System.IO; using System.Xml; using System.Xml.XPath; using System.Collections; using System.Reflection; using System.ComponentModel; using System.Text; namespace XmlNormalizer { /// /// Summary description for Class1. /// class XmlNormalizer { class OptionLetterAttribute:Attribute{ char _c; public OptionLetterAttribute(char c):base(){ _c = c; } public override string ToString() { return _c.ToString(); } } XmlDocument doc; bool _removeWhiteSpace; bool _sortAttributes; bool _removeAttributes; bool _removeNamespacesAndPrefixes; bool _removeText; bool _removeAll; bool _newLines; [OptionLetter('w')] [Description("remove white space")] public bool RemoveWhiteSpace { get {return _removeWhiteSpace;} set {_removeWhiteSpace=value;} } [OptionLetter('s')] [Description("sort attributes")] public bool SortAttributes { get {return _sortAttributes;} set {_sortAttributes=value;} } [OptionLetter('a')] [Description("remove attributes")] public bool RemoveAttributes { get {return _removeAttributes;} set {_removeAttributes=value;} } [OptionLetter('p')] [Description("remove namespaces and prefixes")] public bool RemoveNamespacesAndPrefixes { get {return _removeNamespacesAndPrefixes;} set {_removeNamespacesAndPrefixes=value;} } [OptionLetter('t')] [Description("remove text nodes")] public bool RemoveText { get {return _removeText;} set {_removeText=value;} } [OptionLetter('n')] [Description("remove all except element nodes")] public bool RemoveAll { get {return _removeAll;} set {_removeAll=value;} } [OptionLetter('x')] [Description("insert newlines before elements")] public bool NewLines { get {return _newLines;} set {_newLines=value;} } [OptionLetter('m')] [Description("minimal normalizing")] public bool MinimalNormalizing { get {return false;} } public XmlNormalizer () :this ("") { } public XmlNormalizer (string options) { ParseOptions(options); } public void Process(TextReader rd) { doc=new XmlDocument(); doc.PreserveWhitespace = true; string fileContents = rd.ReadToEnd(); try { doc.LoadXml (fileContents); } catch (Exception x) { StringBuilder sb = new StringBuilder (); sb.Append (""); sb.Append (fileContents); sb.Append (""); doc.LoadXml (sb.ToString ()); } if (RemoveText) RemoveWhiteSpace = true; if (RemoveAll) RemoveNamespacesAndPrefixes = true; XmlDocument newDoc = new XmlDocument(); CopyNodes(newDoc, doc, newDoc); doc=newDoc; } void CopyNodes (XmlDocument newDoc, XmlNode fromParent, XmlNode toParent) { if (fromParent.HasChildNodes) foreach (XmlNode c in fromParent.ChildNodes) CopyNode (newDoc, c, toParent); if (fromParent.Attributes != null) { string [] keys = new string [fromParent.Attributes.Count]; for (int i=0; i /// The main entry point for the application. /// [STAThread] static int Main(string[] args) { if (args.Length < 2 || args[0].Length < 2 || args[0][0] != '-') { PrintUsage(); return 1; } XmlNormalizer norm = new XmlNormalizer (args[0].Substring(1)); if (File.Exists(args[1])) { if (args.Length != 2) { PrintUsage(); return 1; } norm.ProcessFile(new StreamReader (args[1]), Console.Out); } else if (Directory.Exists (args[1])) { if (args.Length != 3) { PrintUsage(); return 1; } norm.ProcessDirectory (args[1], args[2]); } else { Console.Error.WriteLine("Path not found: {0}", args[1]); return 2; } return 0; } static void PrintUsage () { Console.Error.WriteLine("Usage: xmlnorm - "); Console.Error.WriteLine("Or: xmlnorm - "); Console.Error.WriteLine("\tFlags:"); foreach (DictionaryEntry de in XmlNormalizer.GetOptions()) Console.Error.WriteLine ("\t{0}\t{1}", de.Key, de.Value); } #endif } }