Классы XSD Gen, которые ссылаются на общий тип - PullRequest
10 голосов
/ 30 ноября 2011

Я использую XSD для определения моих типов DTO в C #. Я использую XSD.exe для генерации классов из XSD.

У меня есть Common.xsd, который определяет тип адреса, и я хочу использовать его в нескольких классах:

  <xs:complexType name="Address">
    <xs:sequence>
      <xs:element name="Street1" type="xs:string"/>
      <xs:element name="Street2" type="xs:string"/>
      <xs:element name="City" type="xs:string"/>
      <xs:element name="State" type="xs:string"/>
      <xs:element name="Zip" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="Address" type="mhm:Address"/>

Я ссылаюсь на это в компании XSD:

  <xs:include schemaLocation=".\Common.xsd"/>
  <xs:complexType name="Company">
    <xs:sequence>
      <xs:element name="AdmCode" type="xs:string"/>
      <xs:element name="CompanyCode" type="xs:string"/>
      <xs:element name="Name" type="xs:string"/>
      <xs:element ref="mhm:Address"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="Company" type="mhm:Company"/>

И сотрудник XSD:

  <xs:include schemaLocation=".\Common.xsd"/>
  <xs:complexType name="Employee">
    <xs:sequence>
      <xs:element name="EmployeeNumber" type="xs:int"/>
      <xs:element name="FirstName" type="xs:string"/>
      <xs:element name="LastName" type="xs:string"/>
      <xs:element name="Address" type="mhm:Address"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="Employee" type="mhm:Employee"/>

Генерация классов с использованием этой командной строки:

xsd .\XSD\Common.xsd /c /o:. /n:"DomainModel"
xsd .\XSD\Employee.xsd /c /o:. /n:"DomainModel"
xsd .\XSD\Company.xsd /c /o:. /n:"DomainModel"

Когда я собираюсь скомпилировать проект, я обнаружил, что тип Address был создан как в файле класса Company.cs, так и в файле класса Employee.cs.

Как я могу получить тип адреса, сгенерированный только один раз в файле класса Common.cs, а типы Employee и Company используют этот единственный тип адреса?

Ответы [ 2 ]

8 голосов
/ 30 ноября 2011

Вы можете использовать XSD.exe с несколькими аргументами файла:

xsd .\XSD\Common.xsd .\XSD\Employee.xsd .\XSD\Company.xsd /c /o:. /n:"DomainModel"
0 голосов
/ 30 ноября 2011

Вы в основном хотите разделить общие типы на общую сборку, которая является ссылками других ваших типов.У вас есть два варианта:

  1. Разделить их вручную.Я знаю, что это сгенерированный файл, но если ваши исходные схемы довольно статичны, тогда это одноразовое упражнение.
  2. Вместо этого используйте svcutil.exe.Однако это намного сложнее, и на самом деле вы даже не сможете этого сделать, если все ваши схемы не соответствуют определенным рекомендациям.Если вам интересно, смотрите процесс ниже.

Если вам интересен вариант 2 выше, то вот общий процесс:

  1. Извлечение типов из Common.xsd с использованием/ dconly флаг на svcutil.Это создаст файл класса с вашими общими типами.
  2. Скомпилируйте этот класс в сборку
  3. Извлеките типы из A.xsd, используя флаг / r и ссылаясь на вашу сборку CommonTypes.dll.
  4. Сделайте то же самое для B.xsd

Однако этот подход основан на svcutil, использующем DataContractSerializer для выполнения работы, так как флаг / r недоступен для XmlSerializer.И это будет работать, только если ваши схемы придерживаются довольно строгих правил DCS (можно найти здесь: http://msdn.microsoft.com/en-us/library/ms733112.aspx).

Если эти правила не соблюдаются, тогда svcutil вернется к использованию XmlSerializer, которыйне поддерживает флаг / r.

...