65.9K
CodeProject 正在变化。 阅读更多。
Home

XML 架构定义 (XSD) 编辑器和强类型配置类生成器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.82/5 (6投票s)

2009年7月20日

CPOL

5分钟阅读

viewsIcon

40718

downloadIcon

2537

一个能够生成常见 XSD 文档并生成与 XML 架构 (XSD) 文件对应的强类型配置类的编辑器

目录

引言

本文是对 Marc Clifton 的文章 "XML 架构定义 (XSD) 编辑器" 的扩展,点击 此处 查看原文。除了原有的 XML 架构编辑功能外,该应用程序现在还能够根据选定的 XML 架构文件生成强类型配置类。它使用 C# 和 .NET 的 CodeDOM Namespaces 实现。您可以从应用程序界面生成强类型配置类,也可以将该应用程序集成到您的 Visual Studio 项目中,使其在后台透明地生成强类型配置类。第二种方法最为有用,因为您只需要在项目中包含一个 XML 架构 (XSD) 文件,每次修改 XSD 文件时,都会自动生成强类型配置类,并可供使用。

背景

我一直在寻找一种方法,可以根据 XML 架构 (XSD) 文件生成强类型的自定义配置类。由于我找到的方法都没有我列出的所有功能,我决定制作一个工具来实现这一点。我发现 CodeProject 上 Marc Clifton 发布的 XML 架构定义 (XSD) 编辑器易于使用,所以我以此为平台,添加了我需要的功能。

特点

  1. 可以无缝集成到 VS 项目中,自动生成强类型配置类。
  2. 类是根据 XML 架构文件生成的,代表其结构。
  3. 使用 .NET 集合类,方便访问配置数据。

工作原理

1. 创建 XML 架构 (XSD) 文件

  • 如果您没有 XML 架构文件,可以使用 ConfigClassGen.exe 或您喜欢的任何 XML 架构编辑器来创建一个。
  • 如果您已有 XML 架构文件,也可以使用 ConfigClassGen.exe 在使用它生成配置类之前对其进行编辑。
  • 如果您有一个 XML 文件,可以从您的 XML 文件生成 XML 架构文件。要做到这一点,在 Visual Studio 中打开 XML 文件,选择菜单 XML,然后选择创建架构。

以下是演示项目中使用的 XML 架构文件

<?xml version="1.0" encoding="utf-8"?>

<xs:schema id="ConfigClassGenDemo"
    targetNamespace="http://tempuri.org/ConfigClassGenDemo.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/ConfigClassGenDemo.xsd"
    xmlns:mstns="http://tempuri.org/ConfigClassGenDemo.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:element name="DEV">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ClientID" type="xs:int" />
        <xs:element name="ClientName" type="xs:string" />

        <xs:element name="Province" minOccurs="1" maxOccurs="10">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Abbreviation" type="xs:string" />
              <xs:element name="Name" type="xs:string" />
              <xs:element name="Population" type="xs:long" />

            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Contact">
          <xs:complexType>
            <xs:sequence>

              <xs:element name="Name" type="xs:string" />
              <xs:element name="EmailAddress" type="xs:string" minOccurs="1" 
                  maxOccurs="5" />
              <xs:element name="Address">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="StreetAddress" type="xs:string" />

                    <xs:element name="City" type="xs:string" />
                    <xs:element name="Province" type="xs:string" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>

          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

2. 将 XML 架构文件包含到您的 VS 项目中

3. 设置 VS 项目以从 XML 架构文件自动生成配置类

  • ConfigClassGen.exe 复制到您的项目文件夹:$(ProjectDir)。
  • 在解决方案资源管理器窗口中右键单击您的项目名称,选择属性菜单
  • 在项目属性窗口中选择“生成事件”选项卡
  • 在“预生成事件命令行”窗格中,输入以下命令行
$(ProjectDir)ConfigClassGen.exe $(ProjectDir)$(ProjectName).config.xsd $(ProjectDir)AppConfig.cs $(ProjectName)

这使得 ConfigClassGen.exe 在每次编译项目之前,都会根据您的 XML 架构文件生成一个配置文件。

在这种情况下,ConfigClassGen.exe 的第一个命令行参数是 XML 架构文件名:$(ProjectName).config.xsd;第二个参数是配置类文件名:AppConfig.cs;第三个参数是配置类中使用的命名空间:$(ProjectName)。

4. 将自动生成的配置类添加到您的项目中

  • 在您第一次编译项目后,配置类将自动生成。将此文件(在此示例中为 AppConfig.cs)添加到您的项目中。

5. 创建 XML 配置文件

  • 如果您已经有了 XML 配置文件,只需将其添加到您的项目中。请注意,它必须位于 \bin\Debug 文件夹下,该文件夹与您的应用程序可执行文件是同一个文件夹。
  • 如果您没有 XML 配置文件,可以使用 VS 2008 的 XML 架构浏览器,从您的 XML 架构文件生成一个示例 XML 文件作为开始。为此,打开架构文件并右键单击一个节点,然后选择“生成示例 XML 文件”。在 VS 2008 中,您可以将您的架构文件设置为您 XML 文件的架构集,然后在 XML 编辑器中获得验证和智能感知功能。

以下是演示项目中使用的 XML 配置文件

<?xml version="1.0" encoding="utf-8" ?>

<AppConfigSettings>

  <ClientID>123</ClientID>

  <ClientName>ABC Company</ClientName>

  <ResponseFile>
    <ScheduledStartTime>12:00</ScheduledStartTime>
    <DataRangeInHours>24</DataRangeInHours>
  </ResponseFile>

  <Province>
    <Abbreviation>ON</Abbreviation>
    <Name>Ontario</Name>
    <Population>12929000</Population>

  </Province>
  <Province>
    <Abbreviation>AB</Abbreviation>
    <Name>Alberta</Name>
    <Population>3585000</Population>

  </Province>
  <Province>
    <Abbreviation>BC</Abbreviation>
    <Name>British Clumbia</Name>
    <Population>4381000</Population>

  </Province>

  <Contact>
    <Name>Contact One</Name>
    <EmailAddress>contact1@abc.com</EmailAddress>

    <Address>
      <StreetAddress>
        100 King St.
      </StreetAddress>
      <City>Mississauga</City>
      <Province>ON</Province>

    </Address>
  </Contact>
  <Contact>
    <Name>Contact Two</Name>
    <EmailAddress>contact2a@abc.com</EmailAddress>

    <EmailAddress>contact2b@abc.com</EmailAddress>
    <Address>
      <StreetAddress>200 Queen St.</StreetAddress>
      <City>Vancouver</City>

      <Province>BC</Province>
    </Address>
  </Contact>

</AppConfigSettings>

6. 将 App.config 添加到您的项目中

  • 创建 App.config 文件并添加以下内容
<configuration>
    <configSections>
        <!-- type = <name of the handler class>, <assembly name> -->

        <section name="AppConfig" type="[YourNameSpace].AppConfigHandler, <AssenblyName>"/>
    </configSections>

    <AppConfig>
        <!-- Set the configSource to the custom config file -->
        <AppEnvironment configSource="dev.config.xml"/>

    </AppConfig>
</configuration>

<YourNameSpace> 是您在步骤 3 的预生成命令行中使用的第三个参数;dev.config.xml 是您想要使用的配置 XML 文件,当您将应用程序部署到不同环境时,您可以简单地修改此应用程序配置文件中的文件名,以指向不同的自定义 XML 配置文件。

7. 在您的代码中使用配置类

  • 生成的配置类遵循 XML 架构结构,一旦声明了配置类,您将拥有智能感知功能来帮助您获取所需的值。
  • 生成的配置类是强类型的,因此您的代码是类型安全的,您将在编译时捕获任何类型不匹配。
  • 生成的配置类使用了 .NET 集合类,因此您可以使用 foreach 语句来循环遍历集合。
  • 生成的配置类提供了 GetIndexBy<ConfigValue> 函数,因此您可以根据另一个关联的配置值来搜索配置值。
                config = AppConfig.GetConfig("AppConfig");

                Console.Out.WriteLine(string.Format("Client ID: {0}", config.ClientID));
                Console.Out.WriteLine(string.Format("Client Name: {0}",
                    config.ClientName));

                Console.Out.WriteLine();
                Console.Out.WriteLine(string.Format("Selected Province: {0}",
                config.ProvinceCollections[config.ProvinceCollections.GetIndexByAbbreviation(
                    "ON")].Name));

                Console.Out.WriteLine();
                foreach (
                    AppConfig.ProvinceCollection.Province p in config.ProvinceCollections)
                {
                    Console.Out.WriteLine(string.Format("Province: {0} - {1} - {2}",
                        p.Abbreviation, p.Name, p.Population));
                }

                Console.Out.WriteLine();
                foreach (
                    AppConfig.ContactCollection.Contact c in config.ContactCollections)
                {
                    Console.Out.WriteLine(string.Format(
                        "Contact: {0} - {1} - {2} - {3} - {4}",
                        c.Name,
                        c.AddressField.City, c.AddressField.Province,
                        config.ProvinceCollections[
                            config.ProvinceCollections.GetIndexByAbbreviation(
                            c.AddressField.Province)].Name,
                        config.ProvinceCollections[
                            config.ProvinceCollections.GetIndexByAbbreviation(
                            c.AddressField.Province)].Population,
                        c.AddressField.StreetAddress));
                }

注意:除了 Visual Studio 集成之外,您还可以通过应用程序界面生成配置类。要做到这一点:

  • 启动应用程序 ConfigClassGen.exe
  • 加载或创建 XML 架构文件
  • 选择菜单 Schema --> Generate Code 来生成配置类

缺失的功能

  • 它仅支持 string、int 和 long 类型,需要添加对 bool 和 datetime 等其他类型的支持
  • 它只能生成 C# 代码,需要添加对 VB.NET 等其他语言的支持
  • 需要增强生成配置类中的异常处理代码,以提供更详细的错误消息

文件

  • 源代码文件 - 包含配置类生成器应用程序的源代码文件,您可以在下载文件中找到该项目的两个版本,一个用于 Visual Studio 2008,一个用于 Visual Studio 2005。
  • 演示项目 - 一个演示项目,展示了如何将配置类生成器集成到您的项目中。同样,为了方便起见,同时提供了 VS 2005 和 VS 2008 的版本。
  • EXE 文件 - 编译好的可执行文件以及示例 XML 架构文件和 XML 文件。您可以使用它们按照“如何”步骤创建自己的项目。这里有两组文件,一组用于 .NET 2.0,一组用于 .NET 3.5

历史

  • 2009 年 7 月 20 日 - 首次发布
© . All rights reserved.