WSDLs are not very readable, so I wanted to have some sort of developer-friendly documentation for web services as part of our CI build. I found a simple but effective solution: WSDL viewer (by Tomi Vanek), which is an XSLT transformation file that produces nice HTML documentation.

I had to create a custom NAnt task for XSLT transformations since <style> task failed when I tried to do transformations using the WSDL viewer XSLT (it was complaining about some XML elements not being declared):


    <script language="C#" prefix="Brejc.NAntTasks.">
        <code>
            <![CDATA[
   [TaskName("xslt")]
   public class XsltTask : Task
   {
       [TaskAttribute ("inputfile", Required = true)]
       public string InputFile
       {
           get { return inputFile; }
           set { inputFile = value; }
       }

       [TaskAttribute ("outputfile", Required = true)]
       public string OutputFile
       {
           get { return outputFile; }
           set { outputFile = value; }
       }

       [TaskAttribute ("xsltfile", Required = true)]
       public string XsltFile
       {
           get { return xsltFile; }
           set { xsltFile = value; }
       }

       protected override void ExecuteTask ()
       {
           XsltSettings xsltSettings = new XsltSettings (true, true);
           XmlDocument xsltDoc = new XmlDocument();
           xsltDoc.Load (xsltFile);

           XmlUrlResolver resolver = new XmlUrlResolver ();
           XslCompiledTransform transform = new XslCompiledTransform (true);
           transform.Load (xsltDoc, xsltSettings, resolver);

           using (Stream inputStream = File.Open (inputFile, FileMode.Open, FileAccess.Read))
           {
               XmlReader reader = XmlReader.Create (inputStream);
               using (XmlWriter writer = XmlWriter.Create (outputFile))
                   transform.Transform (reader, writer);
           }
       }

       private string inputFile;
       private string outputFile;
       private string xsltFile;
   }
             ]]>
        </code>
        <references>
            <include name="System.Xml.dll"></include>
        </references>
        <imports>
            <import namespace="System.IO"></import>
            <import namespace="System.Xml"></import>
            <import namespace="System.Xml.Xsl"></import>
        </imports>
    </script>

Now all you need is to use this task to create the documentation:


    <target name="docs.wsdl" description="generates wsdl based on the existing web services">
        <mkdir dir="doc\wsdl" unless="${directory::exists(‘doc\wsdl’)}">
        <xslt inputfile="SomeWebService.wsdl">
              outputfile="doc\wsdl\SomeWebService.html"
              xsltfile="lib\WsdlViewer\wsdl-viewer.xsl"/>
    </xslt>
</mkdir></target>