using System; using System.IO; using System.Reflection; using System.Xml; using System.Xml.Schema; using BF = System.Reflection.BindingFlags; class Dtd2XsdDriver { public static void Main (string [] args) { try { Run (args); } catch (Exception ex) { Console.WriteLine ("ERROR: " + ex.Message); } } static void Run (string [] args) { if (args.Length < 1) { Console.WriteLine ("USAGE: mono dtd2xsd.exe instance-xmlfile [output-xsdfile]"); return; } XmlTextReader xtr; if (args [0].EndsWith (".dtd")) xtr = new XmlTextReader ("", XmlNodeType.Document, null); else xtr = new XmlTextReader (args [0]); XmlSchema xsd = Dtd2Xsd.Run (xtr); if (args.Length > 1) xsd.Write (new StreamWriter (args [1])); else xsd.Write (Console.Out); } } public class Dtd2Xsd { public static XmlSchema Run (XmlTextReader xtr) { while (xtr.NodeType != XmlNodeType.DocumentType) { if (!xtr.Read ()) throw new Exception ("DTD did not appeare."); } // Hacky reflection part object impl = xtr; BF flag = BF.NonPublic | BF.Instance; // In Mono NET_2_0 XmlTextReader is just a wrapper which // does not contain DTD directly. FieldInfo fi = typeof (XmlTextReader).GetField ("source", flag); if (fi != null) impl = fi.GetValue (xtr); PropertyInfo pi = impl.GetType ().GetProperty ("DTD", flag); object dtd = pi.GetValue (impl, null); MethodInfo mi = dtd.GetType ().GetMethod ("CreateXsdSchema", flag); object o = mi.Invoke (dtd, null); return (XmlSchema) o; } }