Как я могу смешать неограниченные группы с ограниченными группами в complexType? - PullRequest
1 голос
/ 05 февраля 2009

Я пытаюсь создать инструмент, который может генерировать XSD для XAML, созданного путем сериализации типа в .NET, но это не относится конкретно к .NET.

Допустим, у меня есть тип. Этот тип имеет свойства и является коллекцией.

public class MyType : Collection<CollectedType>
{
  public PType1 PropertyOne {get;set;}
  public PType2 PropertyTwo {get;set;}
}

Сериализуется следующим образом (без построения графа объекта):

<MyType xmlns="clr-namespace:blahblahblah">
  <CollectedType name="First instance in the collection"/>
  <CollectedType name="Second instance in the collection"/>
  <MyType.PropertyOne>
    <PType1 Value = "Serialized object in PropertyOne" />
  </MyType.PropertyOne>
  <MyType.PropertyTwo>
    <PType2 Value = "Serialized object in PropertyTwo" />
  </MyType. PropertyTwo >
</MyType>

При создании XSD для этого типа я могу сказать следующее:

  • MyType - это сложный тип
  • MyType будет содержать ссылку на группу с именем CollectedTypeGroup
    • CollectedTypeGroup содержит элемент CollectedType и элементы для типов, расширяющих CollectedType
  • MyType будет содержать элемент с именем MyType.PropertyOne
    • PType1 - другой сложный тип
  • MyType будет содержать элемент с именем MyType.PropertyTwo
    • PType2 - это еще один сложный тип

Это все относительно легко сделать. Вот кусок сгенерированного xsd:

  <xs:complexType name="MyType">
    <xs:sequence>
      <xs:element name="MyType.PropertyOne" type="PType1"/>
      <xs:element name="MyType.PropertyOne" type="PType1"/>
      <xs:group ref="CollectedTypeGroup"/>
    </xs:sequence>
  </xs:complexType>

Теперь самое сложное. Поскольку XML будет преобразован обратно в граф объектов, у меня есть список ограничений на то, как элементы добавляются в MyType, которые ДОЛЖНЫ БЫТЬ , предписанные схемой. Если эти три требования и только эти три не соблюдаются, у меня возникают проблемы с пользователями, пытающимися использовать мою схему:

1) Элементы, добавленные в MyType , не должны ограничиваться конкретным заказом
2) Элементы, представляющие свойство моего объекта, могут появляться только один раз или не появляться вообще
3) элементы группы должны быть неограниченными ; они могут появляться где угодно в родительском элементе и 0 ... * times

Здесь я ужасно провожу время. Я не могу найти удовлетворительного сочетания вариантов, последовательностей, всего и т. Д., Чтобы удовлетворить эти три требования. Я также попытался поместить элементы в отдельную группу, complexTypes и т. Д. Кажется, ничего не работает.

Как я могу объединить свои элементы и группы в один комплексный тип и соответствовать моим трем требованиям?

Ответы [ 2 ]

1 голос
/ 26 мая 2009

Это озадачивало людей годами, но невозможно определить эту модель контента в XML-схеме.

Единственная частица схемы, которая гарантирует, что ваши элементы появляются один раз или не появляются вообще, и в любом порядке это xsd: all. Однако, как вы, вероятно, уже обнаружили, максимальная граница для элементов в xsd: all равна 1, а не неограничена.

Если бы у вас был элемент контейнера для элементов коллекции, вы могли бы обойтись без этого:

<xs:complexType name="MyType">
    <xs:sequence>
      <xs:element name="MyType.PropertyOne" type="PType1" minOccurs="0"/>
      <xs:element name="MyType.PropertyTwo" type="PType2" minOccurs="0"/>
      <xs:element name="collection" type="CollectionType" minOccurs="0"/>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="CollectionType">
    <xs:sequence>
       <xs:group ref="CollectedTypeGroup"/>
    </xs:sequence>
</xs:complexType>

Извлечение элементов в группы, сложные типы и т. Д. Не поможет вам обойти эту проблему, поскольку процессор Schema упростит его для выполнения проверки.

К вашему сведению, Relax NG не имеет этого ограничения. Вы можете использовать его конструкцию interleave для определения того, что вы ищете (она такая же, как схема 'all', но допускает неограниченных дочерних элементов).

Надеюсь, это поможет.

1 голос
/ 06 февраля 2009

Соответствует ли это вашим потребностям?

  <xs:element name="MyType" type="MyType.Type"/>
    <xs:complexType name="MyType.Type">
      <xs:sequence>
        <xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
        <xs:choice minOccurs="0">
          <xs:sequence>
            <xs:element name="MyType.PropertyOne" type="PType1.Type"/>
            <xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
            <xs:sequence minOccurs="0">
              <xs:element name="MyType.PropertyTwo" type="PType2.Type"/>
              <xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:sequence>
          <xs:sequence>
            <xs:element name="MyType.PropertyTwo" type="PType2.Type"/>
            <xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
            <xs:sequence minOccurs="0">
              <xs:element name="MyType.PropertyOne" type="PType1.Type"/>
              <xs:group ref="CollectedTypeGroup" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:sequence>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
    <xs:group name="CollectedTypeGroup">
      <xs:choice>
        <xs:element name="CollectedType" type="CollectedType.Type"/>
        <xs:element name="DerivedCollectedType" type="CollectedType.Type"/>
        <xs:element name="DerivedCollectedType2" type="CollectedType.Type"/>
      </xs:choice>
    </xs:group>
    <xs:complexType name="CollectedType.Type">
      <xs:attribute name="name" type="xs:string"/>
    </xs:complexType>
    <xs:complexType name="PType1.Type">
      <xs:sequence>
        <xs:element name="PType1">
          <xs:complexType>
            <xs:attribute name="Value" type="xs:string"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:complexType name="PType2.Type">
      <xs:sequence>
        <xs:element name="PType2">
          <xs:complexType>
            <xs:attribute name="Value" type="xs:string"/>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...