Hello, I wrote a little validator for the ecma-provider style docs using xsd. I am not quite finished perfecting the schema, so there are surely some bugs in it. But it should work for checking Gtk# docs before committing, and it helped me find several typos and other non-displaying parts of the docs. It cannot quite make it through monodoc/class as they have some elements not found in the Gtk# docs.
Currently you can use it like this (after applying the patch): monodoc --validate <provider> <files_or_dir> ex. monodoc --validate ecma gtk-sharp/doc Eventually, additional schemas could be made for the other formats as well. For completeness sake, I am aware of the old valdoc but it uses relaxng and the older format, and I was in the process of learning xsd. Last, it could be interesting for editing to use some sort of validation, but I have not looked into that or if validating fragments are possible.
Index: monodoc.in =================================================================== RCS file: /cvs/public/monodoc/monodoc.in,v retrieving revision 1.12 diff -u -r1.12 monodoc.in --- monodoc.in 3 Jun 2004 11:08:14 -0000 1.12 +++ monodoc.in 25 Aug 2004 01:59:56 -0000 @@ -28,6 +28,10 @@ shift; exec mono $monodocdir/updater.exe "$@" ;; + x--validate) + shift; + exec mono $monodocdir/validate.exe "$@" + ;; x--help) echo "Usage is:" echo "monodoc [options]" @@ -41,6 +45,7 @@ echo " --make-index create the index" echo " --merge-changes CHANGE_FILE [TARGET_DIR]" echo " --normalize format a documentation file consistently" + echo " --validate validate the xml file(s)" echo " TOPIC display the browser at TOPIC (ex. N:System)" exit 0 ;; Index: browser/Makefile.am =================================================================== RCS file: /cvs/public/monodoc/browser/Makefile.am,v retrieving revision 1.63 diff -u -r1.63 Makefile.am --- browser/Makefile.am 3 Aug 2004 04:24:00 -0000 1.63 +++ browser/Makefile.am 25 Aug 2004 01:59:56 -0000 @@ -1,7 +1,7 @@ assemblydir = $(libdir) -monodoc_DATA = browser.exe assembler.exe normalize.exe monodoc.xml mod.exe +monodoc_DATA = browser.exe assembler.exe normalize.exe monodoc.xml mod.exe validate.exe noinst_DATA = monodoc.dll monodoc.dll.config -CLEANFILES = monodoc.dll assembler.exe browser.exe normalize.exe mod.exe +CLEANFILES = monodoc.dll assembler.exe browser.exe normalize.exe mod.exe validate.exe DISTCLEANFILE = AssemblyInfo.cs CSC=mcs @@ -42,17 +42,21 @@ $(srcdir)/admin.cs \ $(srcdir)/Contributions.cs +validate_sources = \ + $(srcdir)/validate.cs + browser_assemblies = -pkg:gtkhtml-sharp -pkg:glade-sharp -r:System.Web.Services EXTRA_DIST = \ $(monodoc_sources) $(assembler_sources) \ $(dump_sources) $(browser_sources) \ + $(validate_sources) \ browser.glade monodoc.xml mono-ecma.xsl \ normalize.cs monodoc.dll.config.in \ ecmaspec-html.xsl mod.cs \ AssemblyInfo.cs.in -monodoc_FILES = browser.exe assembler.exe normalize.exe admin.exe +monodoc_FILES = browser.exe assembler.exe normalize.exe admin.exe validate.exe assembler.exe: $(assembler_sources) monodoc.dll $(CSC) /debug /out:assembler.exe $(assembler_sources) -r:ICSharpCode.SharpZipLib.dll -r:./monodoc.dll @@ -68,6 +72,9 @@ normalize.exe: normalize.cs $(CSC) $(srcdir)/normalize.cs -out:normalize.exe + +validate.exe: validate.cs monodoc-ecma.xsd + $(CSC) $(srcdir)/validate.cs -out:validate.exe /resource:$(srcdir)/monodoc-ecma.xsd,monodoc-ecma.xsd mono.pub: $(top_srcdir)/mono.pub cp $(top_srcdir)/mono.pub . Index: browser/monodoc-ecma.xsd =================================================================== RCS file: browser/monodoc-ecma.xsd diff -N browser/monodoc-ecma.xsd --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ browser/monodoc-ecma.xsd 25 Aug 2004 01:59:56 -0000 @@ -0,0 +1,627 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Author: John Luke <[EMAIL PROTECTED]> +This is a (not very strict) schema for the monodoc +ecma-provider format. +TODO: +make base type for summary, remarks, returns, etc +alias duplicate attributes +make stricter in order and occurance +add masterdoc support? +--> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <!-- define attributes --> + <xs:attribute name="argnames" type="xs:string" /> + <xs:attribute name="cref" type="xs:string" /> + <xs:attribute name="Deprecated" type="xs:boolean" /> + <xs:attribute name="FullName" type="xs:string" /> + <xs:attribute name="FullNameSP" type="xs:string" /> + <xs:attribute name="inherited" type="xs:string" /> + <xs:attribute name="language" type="xs:string" /> + <xs:attribute name="Language" type="xs:string" /> + <xs:attribute name="lang" type="xs:string" /> + <xs:attribute name="langword" type="xs:string" /> + <xs:attribute name="location" type="xs:string" /> + <xs:attribute name="Maintainer" type="xs:string" /> + <xs:attribute name="MemberName" type="xs:string" /> + <xs:attribute name="name" type="xs:string" /> + <xs:attribute name="Name" type="xs:string" /> + <xs:attribute name="namespace" type="xs:string" /> + <xs:attribute name="propertytype" type="xs:string" /> + <xs:attribute name="qualify" type="xs:boolean" /> + <xs:attribute name="RefType" type="xs:string" /> + <xs:attribute name="returntype" type="xs:string" /> + <xs:attribute name="source" type="xs:string" /> + <xs:attribute name="subset" type="xs:string" /> + <xs:attribute name="Value" type="xs:string" /> + <xs:attribute name="type" type="xs:string" /> + <xs:attribute name="Type" type="xs:string" /> + + <!-- define simple elements --> + <xs:element name="AssemblyName" type="xs:string" /> + <xs:element name="AssemblyPublicKey" type="xs:string" /> + <xs:element name="AssemblyVersion" type="xs:string" /> + <xs:element name="AssemblyCulture" type="xs:string" /> + <xs:element name="AttributeName" type="xs:string" /> + <xs:element name="BaseTypeName" type="xs:string" /> + <xs:element name="Excluded" type="xs:string" /> + <xs:element name="ExcludedLibrary" type="xs:string" /> + <xs:element name="ExcludedLibraryName" type="xs:string" /> + <xs:element name="ExcludedTypeName" type="xs:string" /> + <xs:element name="InterfaceName" type="xs:string" /> + <xs:element name="li" type="xs:string" /> + <xs:element name="MemberOfLibrary" type="xs:string" /> + <xs:element name="MemberType" type="xs:string" /> + <xs:element name="MemberValue" type="xs:string" /> + <xs:element name="onequarter" type="xs:string" /> + <xs:element name="ReturnType" type="xs:string" /> + <xs:element name="sub" type="xs:string" /> + <xs:element name="sup" type="xs:string" /> + <xs:element name="TypeExcluded" type="xs:string" /> + + <!-- define complex elements --> + <xs:element name="altmember"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute ref="cref" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + + <xs:element name="AssemblyInfo"> + <xs:complexType> + <xs:sequence> + <xs:element ref="AssemblyName" minOccurs="0" /> + <xs:element ref="AssemblyPublicKey" minOccurs="0" /> + <xs:element ref="AssemblyVersion" minOccurs="0" /> + <xs:element ref="AssemblyCulture" minOccurs="0" /> + <xs:element ref="Attributes" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="Attribute"> + <xs:complexType> + <xs:sequence> + <xs:element ref="AttributeName" /> + <xs:element ref="Excluded" minOccurs="0" /> + <xs:element ref="ExcludedTypeName" minOccurs="0" /> + <xs:element ref="ExcludedLibraryName" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="Attributes"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Attribute" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="Base"> + <xs:complexType> + <xs:sequence> + <xs:element ref="BaseTypeName" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="block"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + <xs:element ref="list" /> + </xs:choice> + <xs:attribute ref="subset" /> + <xs:attribute ref="type" /> + </xs:complexType> + </xs:element> + + <xs:element name="c"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="para" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="class"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="constructor" /> + <xs:element ref="property" /> + <xs:element ref="method" /> + <xs:element ref="field" /> + <xs:element ref="operator" /> + <xs:element ref="event" /> + <xs:element ref="enum" /> + <xs:element ref="class" /> + <xs:element ref="struct" /> + <xs:element ref="interface" /> + <xs:element ref="delegate" /> + </xs:choice> + <xs:attribute ref="name" /> + <xs:attribute ref="namespace" /> + </xs:complexType> + </xs:element> + + <xs:element name="code"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute ref="lang" /> + <xs:attribute ref="language" /> + <xs:attribute ref="source" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + + <xs:element name="constructor"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="argnames" /> + </xs:complexType> + </xs:element> + + <xs:element name="delegate"> + <xs:complexType> + <xs:choice maxOccurs="unbounded"> + <xs:element ref="constructor" /> + <xs:element ref="method" /> + <xs:element ref="property" /> + <xs:element ref="operator" /> + </xs:choice> + <xs:attribute ref="name" /> + <xs:attribute ref="namespace" /> + </xs:complexType> + </xs:element> + + <xs:element name="description"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="see" /> + <xs:element ref="paramref" /> + <xs:element ref="para" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="Docs"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="summary" /> + <xs:element ref="param" /> + <xs:element ref="exception" /> + <xs:element ref="returns" /> + <xs:element ref="remarks" /> + <xs:element ref="example" /> + <xs:element ref="value" /> + <xs:element ref="permission" /> + <xs:element ref="altmember" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="enum"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="field" /> + <xs:element ref="method" /> + </xs:choice> + <xs:attribute ref="name" /> + <xs:attribute ref="namespace" /> + </xs:complexType> + </xs:element> + + <xs:element name="event"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="inherited" /> + </xs:complexType> + </xs:element> + + <xs:element name="example"> + <xs:complexType> + <xs:choice maxOccurs="unbounded"> + <xs:element ref="para" /> + <xs:element ref="code" /> + <xs:element ref="c" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="exception"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + </xs:choice> + <xs:attribute ref="cref" /> + </xs:complexType> + </xs:element> + + <xs:element name="field"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="inherited" /> + </xs:complexType> + </xs:element> + + <xs:element name="interface"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="constructor" /> + <xs:element ref="property" /> + <xs:element ref="method" /> + <xs:element ref="field" /> + <xs:element ref="event" /> + </xs:choice> + <xs:attribute ref="name" /> + <xs:attribute ref="namespace" /> + </xs:complexType> + </xs:element> + + <xs:element name="Interface"> + <xs:complexType> + <xs:sequence> + <xs:element ref="InterfaceName" /> + <xs:element ref="Excluded" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="Interfaces"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Interface" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="item"> + <xs:complexType> + <xs:sequence> + <xs:element ref="term" minOccurs="1" maxOccurs="1" /> + <xs:element ref="description" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="link"> + <xs:complexType> + <xs:simpleContent> + <xs:extension base="xs:string"> + <xs:attribute ref="location" /> + </xs:extension> + </xs:simpleContent> + </xs:complexType> + </xs:element> + + <xs:element name="list"> + <xs:complexType> + <xs:sequence> + <xs:element ref="listheader" minOccurs="0" maxOccurs="1" /> + <xs:element ref="item" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + <xs:attribute name="type" type="xs:string" /> + </xs:complexType> + </xs:element> + + <xs:element name="listheader"> + <xs:complexType> + <xs:sequence> + <xs:element ref="term" /> + <xs:element ref="description" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="masterdoc"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="class" /> + <xs:element ref="delegate" /> + <xs:element ref="interface" /> + <xs:element ref="struct" /> + <xs:element ref="enum" /> + </xs:choice> + <xs:attribute name="assembly" type="xs:string" /> + </xs:complexType> + </xs:element> + + <xs:element name="MemberSignature"> + <xs:complexType> + <xs:attribute ref="Language" /> + <xs:attribute ref="Value" /> + </xs:complexType> + </xs:element> + + <xs:element name="Member"> + <xs:complexType> + <xs:sequence> + <xs:element ref="MemberSignature" maxOccurs="2" /> + <xs:element ref="MemberType" maxOccurs="1" /> + <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" /> + <xs:element ref="ReturnValue" minOccurs="0" maxOccurs="1" /> + <xs:element ref="Parameters" minOccurs="0" maxOccurs="1" /> + <xs:element ref="MemberValue" minOccurs="0" maxOccurs="1" /> + <xs:element ref="Docs" maxOccurs="1" /> + <xs:element ref="Excluded" minOccurs="0" maxOccurs="1" /> + <xs:element ref="ExcludedLibrary" minOccurs="0" maxOccurs="5" /> + </xs:sequence> + <xs:attribute ref="MemberName" /> + <xs:attribute ref="Deprecated" /> + </xs:complexType> + </xs:element> + + <xs:element name="Members"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Member" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="method"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="argnames" /> + <xs:attribute ref="inherited" /> + <xs:attribute ref="returntype" /> + </xs:complexType> + </xs:element> + + <xs:element name="Namespace"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Docs" maxOccurs="1" /> + </xs:sequence> + <xs:attribute ref="Name" /> + <xs:attribute ref="FullName" /> + <xs:attribute ref="FullNameSP" /> + <xs:attribute ref="Maintainer" /> + </xs:complexType> + </xs:element> + + <xs:element name="operator"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="argnames" /> + </xs:complexType> + </xs:element> + + <xs:element name="para"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="block" /> + <xs:element ref="see" /> + <xs:element ref="list" /> + <xs:element ref="link" /> + <xs:element ref="ul" /> + <xs:element ref="example" /> + <xs:element ref="paramref" /> + <xs:element ref="c" /> + <xs:element ref="onequarter" /> + <xs:element ref="sub" /> + <xs:element ref="sup" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="param"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="see" /> + <xs:element ref="block" /> + <xs:element ref="paramref" /> + <xs:element ref="para" /> + </xs:choice> + <xs:attribute ref="name" use="required" /> + </xs:complexType> + </xs:element> + + <xs:element name="paramref"> + <xs:complexType> + <xs:attribute ref="name" use="required" /> + </xs:complexType> + </xs:element> + + <xs:element name="Parameter"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Attributes" minOccurs="0" maxOccurs="1" /> + </xs:sequence> + <xs:attribute ref="Name" /> + <xs:attribute ref="Type" /> + <xs:attribute ref="RefType" /> + </xs:complexType> + </xs:element> + + <xs:element name="Parameters"> + <xs:complexType> + <xs:sequence> + <xs:element ref="Parameter" minOccurs="0" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="permission"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="see" /> + </xs:choice> + <xs:attribute ref="cref" /> + </xs:complexType> + </xs:element> + + <xs:element name="property"> + <xs:complexType> + <xs:attribute ref="name" /> + <xs:attribute ref="inherited" /> + <xs:attribute ref="propertytype" /> + </xs:complexType> + </xs:element> + + <xs:element name="remarks"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="block" /> + <xs:element ref="code" /> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + <xs:element ref="ul" /> + <xs:element ref="example" /> + <xs:element ref="list" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="returns"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="list" /> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + <xs:element ref="ul" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="ReturnValue"> + <xs:complexType> + <xs:sequence> + <xs:element ref="ReturnType" minOccurs="0" maxOccurs="1" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="see"> + <xs:complexType> + <xs:attribute ref="cref" /> + <xs:attribute ref="langword" /> + <xs:attribute ref="qualify" /> + </xs:complexType> + </xs:element> + + <xs:element name="struct"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="constructor" /> + <xs:element ref="property" /> + <xs:element ref="method" /> + <xs:element ref="field" /> + <xs:element ref="operator" /> + <xs:element ref="struct" /> + <xs:element ref="class" /> + </xs:choice> + <xs:attribute ref="name" /> + <xs:attribute ref="namespace" /> + </xs:complexType> + </xs:element> + + <xs:element name="summary"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="block" /> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + <xs:element ref="ul" /> + <xs:element ref="list" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="term"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="see" /> + <xs:element ref="para" /> + <xs:element ref="param" /> + <xs:element ref="paramref" /> + </xs:choice> + </xs:complexType> + </xs:element> + + <xs:element name="ThreadingSafetyStatement"> + <xs:complexType mixed="true"> + <xs:sequence> + <xs:element ref="link" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="ThreadSafetyStatement"> + <xs:complexType mixed="true"> + <xs:sequence> + <xs:element ref="link" minOccurs="0" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="Type"> + <xs:complexType> + <xs:choice maxOccurs="unbounded"> + <xs:element ref="TypeSignature" minOccurs="1" /> + <xs:element ref="MemberOfLibrary" minOccurs="0" /> + <xs:element ref="AssemblyInfo" minOccurs="1" /> + <xs:element ref="ThreadingSafetyStatement" minOccurs="0" /> + <xs:element ref="ThreadSafetyStatement" minOccurs="0" /> + <xs:element ref="Docs" minOccurs="1" /> + <xs:element ref="Base" minOccurs="1" /> + <xs:element ref="Interfaces" minOccurs="1" /> + <xs:element ref="Attributes" minOccurs="1" /> + <xs:element ref="Members" minOccurs="1" /> + <xs:element ref="Parameters" minOccurs="0" /> + <xs:element ref="ReturnValue" minOccurs="0" /> + <xs:element ref="TypeExcluded" minOccurs="0" /> + </xs:choice> + <xs:attribute ref="Name" use="required" /> + <xs:attribute ref="FullName" use="required" /> + <xs:attribute ref="FullNameSP" /> + <xs:attribute ref="Maintainer" /> + </xs:complexType> + </xs:element> + + <xs:element name="TypeSignature"> + <xs:complexType> + <xs:attribute ref="Language" use="required" /> + <xs:attribute ref="Value" use="required" /> + <xs:attribute ref="Maintainer" /> + </xs:complexType> + </xs:element> + + <xs:element name="ul"> + <xs:complexType> + <xs:sequence> + <xs:element ref="li" minOccurs="1" maxOccurs="unbounded" /> + </xs:sequence> + </xs:complexType> + </xs:element> + + <xs:element name="value"> + <xs:complexType mixed="true"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element ref="block" /> + <xs:element ref="para" /> + <xs:element ref="paramref" /> + <xs:element ref="see" /> + <xs:element ref="ul" /> + <xs:element ref="example" /> + <xs:element ref="list" /> + </xs:choice> + </xs:complexType> + </xs:element> + +</xs:schema> + Index: browser/validate.cs =================================================================== RCS file: browser/validate.cs diff -N browser/validate.cs --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ browser/validate.cs 25 Aug 2004 01:59:56 -0000 @@ -0,0 +1,112 @@ +using System; +using System.IO; +using System.Reflection; +using System.Xml; +using System.Xml.Schema; + +namespace MonoDoc +{ + public class Validate + { + static XmlValidatingReader reader; + static XmlSchema schema; + static long errors = 0; + static bool IsValid = true; + + public static void Main (string[] args) + { + if (args.Length < 2) { + PrintUsage (); + } + + Stream s = null; + + switch (args[0]) { + case "ecma": + s = Assembly.GetExecutingAssembly ().GetManifestResourceStream ("monodoc-ecma.xsd"); + break; + default: + Console.WriteLine ("Unknown provider: {0}", args[0]); + Environment.Exit (0); + break; + } + + if (s == null) { + Console.WriteLine ("ERROR: schema for {0} was not found", args[0]); + Environment.Exit (1); + } + + schema = XmlSchema.Read (s, null); + schema.Compile (null); + + // skip args[0] because it is the provider name + for (int i = 1; i < args.Length; i++) { + string arg = args[i]; + if (IsMonodocFile (arg)) + ValidateFile (arg); + + if (Directory.Exists (arg)) + { + RecurseDirectory (arg); + } + } + + Console.WriteLine ("Total validation errors: {0}", errors); + } + + static void PrintUsage () + { + Console.WriteLine ("usage: normalize.exe <provider> <files>"); + Environment.Exit (0); + } + + static void ValidateFile (string file) + { + IsValid = true; + Console.WriteLine ("Checking {0}", file); + reader = new XmlValidatingReader (new XmlTextReader (file)); + reader.ValidationType = ValidationType.Schema; + reader.Schemas.Add (schema); + reader.ValidationEventHandler += new ValidationEventHandler (OnValidationEvent); + while (reader.Read ()) { + // do nothing + } + reader.Close (); + + if (IsValid) + Console.WriteLine ("{0} is valid.", file); + } + + static void RecurseDirectory (string dir) + { + string[] files = Directory.GetFiles (dir, "*.xml"); + foreach (string f in files) + { + if (IsMonodocFile (f)) + ValidateFile (f); + } + + string[] dirs = Directory.GetDirectories (dir); + foreach (string d in dirs) + RecurseDirectory (d); + } + + static void OnValidationEvent (object sender, ValidationEventArgs a) + { + if (IsValid) + IsValid = false; + errors ++; + Console.WriteLine (a.Message); + } + + static bool IsMonodocFile (string file) + { + if (File.Exists (file) && Path.GetExtension (file).ToLower () == ".xml") + return true; + else + return false; + + } + } +} +