如何:使用 CodeDOM 创建 XML 文档文件

可使用 CodeDOM 创建生成 XML 文档的代码。 该进程包括创建包含 XML 文档注释的 CodeDOM 图、生成代码和通过创建 XML 文档输出的编译器选项编译生成的代码。

创建 CodeDOM 图

  1. 为示例应用程序创建包含 CodeDOM 图的 CodeCompileUnit

  2. 使用 CodeCommentStatement 构造函数(docComment 参数设置为 true)创建 XML 文档注释元素和文本。

    CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");
    
    class1.Comments.Add(new CodeCommentStatement("<summary>", true));
    class1.Comments.Add(new CodeCommentStatement(
        "Create a Hello World application.", true));
    class1.Comments.Add(new CodeCommentStatement("</summary>", true));
    class1.Comments.Add(new CodeCommentStatement(
        @"<seealso cref=" + '"' + "Class1.Main" + '"' + "/>", true));
    
    // Add the new type to the namespace type collection.
    samples.Types.Add(class1);
    
    // Declare a new code entry point method.
    CodeEntryPointMethod start = new CodeEntryPointMethod();
    start.Comments.Add(new CodeCommentStatement("<summary>", true));
    start.Comments.Add(new CodeCommentStatement(
        "Main method for HelloWorld application.", true));
    start.Comments.Add(new CodeCommentStatement(
        @"<para>Add a new paragraph to the description.</para>", true));
    start.Comments.Add(new CodeCommentStatement("</summary>", true));
    
    Dim class1 As New CodeTypeDeclaration("Class1")
    
    class1.Comments.Add(New CodeCommentStatement("<summary>", True))
    class1.Comments.Add(New CodeCommentStatement( _
        "Create a Hello World application.", True))
    class1.Comments.Add(New CodeCommentStatement("</summary>", True))
    class1.Comments.Add(New CodeCommentStatement( _
        "<seealso cref=" & ControlChars.Quote & "Class1.Main" & _
        ControlChars.Quote & "/>", True))
    
    ' Add the new type to the namespace type collection.
    samples.Types.Add(class1)
    
    ' Declare a new code entry point method.
    Dim start As New CodeEntryPointMethod()
    start.Comments.Add(New CodeCommentStatement("<summary>", True))
    start.Comments.Add(New CodeCommentStatement( _
        "Main method for HelloWorld application.", True))
    start.Comments.Add(New CodeCommentStatement( _
        "<para>Add a new paragraph to the description.</para>", True))
    start.Comments.Add(New CodeCommentStatement("</summary>", True))
    

从 CodeCompileUnit 生成代码

使用 GenerateCodeFromCompileUnit 方法生成代码并创建要编译的源文件。

StreamWriter sourceFile = new StreamWriter(sourceFileName);
provider.GenerateCodeFromCompileUnit(cu, sourceFile, null);
sourceFile.Close();
Dim sourceFile As New StreamWriter(sourceFileName)

LogMessage("Generating code...")
provider.GenerateCodeFromCompileUnit(cu, sourceFile, Nothing)
sourceFile.Close()

编译代码并生成文档文件

将 /doc 编译器选项添加到 CompilerParameters 对象的 CompilerOptions 属性中,然后将该对象传递给 CompileAssemblyFromFile 方法,以便在编译代码时创建 XML 文档文件。

CompilerParameters opt = new CompilerParameters(new string[]{
                          "System.dll" });
opt.GenerateExecutable = true;
opt.OutputAssembly = "HelloWorld.exe";
opt.TreatWarningsAsErrors = true;
opt.IncludeDebugInformation = true;
opt.GenerateInMemory = true;
opt.CompilerOptions = "/doc:HelloWorldDoc.xml";

CompilerResults results;

LogMessage("Compiling with " + providerName);
results = provider.CompileAssemblyFromFile(opt, sourceFileName);
Dim opt As New CompilerParameters(New String() {"System.dll"})
opt.GenerateExecutable = True
opt.OutputAssembly = "HelloWorld.exe"
opt.TreatWarningsAsErrors = True
opt.IncludeDebugInformation = True
opt.GenerateInMemory = True
opt.CompilerOptions = "/doc"

Dim results As CompilerResults

LogMessage(("Compiling with " & providerName))
results = provider.CompileAssemblyFromFile(opt, sourceFileName)

示例

以下代码示例创建一个包含文档注释的 CodeDOM 图,从该图生成一个代码文件,然后编译该文件并创建一个关联的 XML 文档文件。

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Text.RegularExpressions;

namespace BasicCodeDomApp
{
    class Program
    {
        static string providerName = "cs";
        static string sourceFileName = "test.cs";
        static void Main(string[] args)
        {
            CodeDomProvider provider =
                CodeDomProvider.CreateProvider(providerName);

            LogMessage("Building CodeDOM graph...");

            CodeCompileUnit cu = new CodeCompileUnit();

            cu = BuildHelloWorldGraph();

            StreamWriter sourceFile = new StreamWriter(sourceFileName);
            provider.GenerateCodeFromCompileUnit(cu, sourceFile, null);
            sourceFile.Close();

            CompilerParameters opt = new CompilerParameters(new string[]{
                                      "System.dll" });
            opt.GenerateExecutable = true;
            opt.OutputAssembly = "HelloWorld.exe";
            opt.TreatWarningsAsErrors = true;
            opt.IncludeDebugInformation = true;
            opt.GenerateInMemory = true;
            opt.CompilerOptions = "/doc:HelloWorldDoc.xml";

            CompilerResults results;

            LogMessage("Compiling with " + providerName);
            results = provider.CompileAssemblyFromFile(opt, sourceFileName);

            OutputResults(results);
            if (results.NativeCompilerReturnValue != 0)
            {
                LogMessage("");
                LogMessage("Compilation failed.");
            }
            else
            {
                LogMessage("");
                LogMessage("Demo completed successfully.");
            }
            File.Delete(sourceFileName);
        }

        // Build a Hello World program graph using
        // System.CodeDom types.
        public static CodeCompileUnit BuildHelloWorldGraph()
        {
            // Create a new CodeCompileUnit to contain
            // the program graph.
            CodeCompileUnit compileUnit = new CodeCompileUnit();

            // Declare a new namespace called Samples.
            CodeNamespace samples = new CodeNamespace("Samples");
            // Add the new namespace to the compile unit.
            compileUnit.Namespaces.Add(samples);

            // Add the new namespace import for the System namespace.
            samples.Imports.Add(new CodeNamespaceImport("System"));

            // Declare a new type called Class1.
            CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");

            class1.Comments.Add(new CodeCommentStatement("<summary>", true));
            class1.Comments.Add(new CodeCommentStatement(
                "Create a Hello World application.", true));
            class1.Comments.Add(new CodeCommentStatement("</summary>", true));
            class1.Comments.Add(new CodeCommentStatement(
                @"<seealso cref=" + '"' + "Class1.Main" + '"' + "/>", true));

            // Add the new type to the namespace type collection.
            samples.Types.Add(class1);

            // Declare a new code entry point method.
            CodeEntryPointMethod start = new CodeEntryPointMethod();
            start.Comments.Add(new CodeCommentStatement("<summary>", true));
            start.Comments.Add(new CodeCommentStatement(
                "Main method for HelloWorld application.", true));
            start.Comments.Add(new CodeCommentStatement(
                @"<para>Add a new paragraph to the description.</para>", true));
            start.Comments.Add(new CodeCommentStatement("</summary>", true));

            // Create a type reference for the System.Console class.
            CodeTypeReferenceExpression csSystemConsoleType =
                new CodeTypeReferenceExpression("System.Console");

            // Build a Console.WriteLine statement.
            CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine",
                new CodePrimitiveExpression("Hello World!"));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs1);

            // Build another Console.WriteLine statement.
            CodeMethodInvokeExpression cs2 = new CodeMethodInvokeExpression(
                csSystemConsoleType, "WriteLine", new CodePrimitiveExpression(
                "Press the ENTER key to continue."));

            // Add the WriteLine call to the statement collection.
            start.Statements.Add(cs2);

            // Build a call to System.Console.ReadLine.
            CodeMethodInvokeExpression csReadLine =
                new CodeMethodInvokeExpression(csSystemConsoleType, "ReadLine");

            // Add the ReadLine statement.
            start.Statements.Add(csReadLine);

            // Add the code entry point method to
            // the Members collection of the type.
            class1.Members.Add(start);

            return compileUnit;
        }
        static void LogMessage(string text)
        {
            Console.WriteLine(text);
        }

        static void OutputResults(CompilerResults results)
        {
            LogMessage("NativeCompilerReturnValue=" +
                results.NativeCompilerReturnValue.ToString());
            foreach (string s in results.Output)
            {
                LogMessage(s);
            }
        }
    }
}
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.IO
Imports System.Text.RegularExpressions

Class Program
    Private Shared providerName As String = "vb"
    Private Shared sourceFileName As String = "test.vb"

    Shared Sub Main(ByVal args() As String)
        Dim provider As CodeDomProvider = _
            CodeDomProvider.CreateProvider(providerName)

        LogMessage("Building CodeDOM graph...")

        Dim cu As New CodeCompileUnit()

        cu = BuildHelloWorldGraph()

        Dim sourceFile As New StreamWriter(sourceFileName)

        LogMessage("Generating code...")
        provider.GenerateCodeFromCompileUnit(cu, sourceFile, Nothing)
        sourceFile.Close()

        Dim opt As New CompilerParameters(New String() {"System.dll"})
        opt.GenerateExecutable = True
        opt.OutputAssembly = "HelloWorld.exe"
        opt.TreatWarningsAsErrors = True
        opt.IncludeDebugInformation = True
        opt.GenerateInMemory = True
        opt.CompilerOptions = "/doc"

        Dim results As CompilerResults

        LogMessage(("Compiling with " & providerName))
        results = provider.CompileAssemblyFromFile(opt, sourceFileName)

        OutputResults(results)
        If results.NativeCompilerReturnValue <> 0 Then
            LogMessage("")
            LogMessage("Compilation failed.")
        Else
            LogMessage("")
            LogMessage("Demo completed successfully.")
        End If
        File.Delete(sourceFileName)

    End Sub

    ' Build a Hello World program graph using System.CodeDom types.
    Public Shared Function BuildHelloWorldGraph() As CodeCompileUnit
        ' Create a new CodeCompileUnit to contain 
        ' the program graph.
        Dim compileUnit As New CodeCompileUnit()

        ' Declare a new namespace called Samples.
        Dim samples As New CodeNamespace("Samples")
        ' Add the new namespace to the compile unit.
        compileUnit.Namespaces.Add(samples)

        ' Add the new namespace import for the System namespace.
        samples.Imports.Add(New CodeNamespaceImport("System"))

        ' Declare a new type called Class1.
        Dim class1 As New CodeTypeDeclaration("Class1")

        class1.Comments.Add(New CodeCommentStatement("<summary>", True))
        class1.Comments.Add(New CodeCommentStatement( _
            "Create a Hello World application.", True))
        class1.Comments.Add(New CodeCommentStatement("</summary>", True))
        class1.Comments.Add(New CodeCommentStatement( _
            "<seealso cref=" & ControlChars.Quote & "Class1.Main" & _
            ControlChars.Quote & "/>", True))

        ' Add the new type to the namespace type collection.
        samples.Types.Add(class1)

        ' Declare a new code entry point method.
        Dim start As New CodeEntryPointMethod()
        start.Comments.Add(New CodeCommentStatement("<summary>", True))
        start.Comments.Add(New CodeCommentStatement( _
            "Main method for HelloWorld application.", True))
        start.Comments.Add(New CodeCommentStatement( _
            "<para>Add a new paragraph to the description.</para>", True))
        start.Comments.Add(New CodeCommentStatement("</summary>", True))
        ' Create a type reference for the System.Console class.
        Dim csSystemConsoleType As New CodeTypeReferenceExpression( _
            "System.Console")

        ' Build a Console.WriteLine statement.
        Dim cs1 As New CodeMethodInvokeExpression(csSystemConsoleType, _
            "WriteLine", New CodePrimitiveExpression("Hello World!"))

        ' Add the WriteLine call to the statement collection.
        start.Statements.Add(cs1)

        ' Build another Console.WriteLine statement.
        Dim cs2 As New CodeMethodInvokeExpression(csSystemConsoleType, _
            "WriteLine", New CodePrimitiveExpression( _
            "Press the ENTER key to continue."))

        ' Add the WriteLine call to the statement collection.
        start.Statements.Add(cs2)

        ' Build a call to System.Console.ReadLine.
        Dim csReadLine As New CodeMethodInvokeExpression( _
            csSystemConsoleType, "ReadLine")

        ' Add the ReadLine statement.
        start.Statements.Add(csReadLine)

        ' Add the code entry point method to
        ' the Members collection of the type.
        class1.Members.Add(start)

        Return compileUnit

    End Function 'BuildHelloWorldGraph

    Shared Sub LogMessage(ByVal [text] As String)
        Console.WriteLine([text])

    End Sub

    Shared Sub OutputResults(ByVal results As CompilerResults)
        LogMessage(("NativeCompilerReturnValue=" & _
            results.NativeCompilerReturnValue.ToString()))
        Dim s As String
        For Each s In results.Output
            LogMessage(s)
        Next s

    End Sub
End Class

该代码示例在 HelloWorldDoc.xml 文件中创建以下 XML 文档。

<?xml version="1.0" ?>
<doc>
  <assembly>
    <name>HelloWorld</name>
  </assembly>
  <members>
    <member name="T:Samples.Class1">
      <summary>
        Create a Hello World application.
      </summary>
      <seealso cref="M:Samples.Class1.Main" />
    </member>
    <member name="M:Samples.Class1.Main">
      <summary>
        Main method for HelloWorld application.
        <para>Add a new paragraph to the description.</para>
      </summary>
    </member>
  </members>
</doc>

编译权限

需要 FullTrust 权限集才可成功执行此代码示例。

请参阅