xsd один и тот же элемент, разные типы? - PullRequest
15 голосов
/ 20 августа 2009

У меня есть ситуация, когда элемент в XML-файле может быть двух разных типов в XSD.

То, что я хочу сделать, - это сначала проверить введенное значение для более строгого типа (если это лицо, заполняющее форму), а если оно не выполнено, проверить его для менее строгого типа (если оно организация, которая заполняет форму), в противном случае допустим сбой проверки, если она вообще не проверяется.

Так что это в основном это:

<xsd:complexType name="ForminfoType"> `
    <xsd:sequence>
        <xsd:element name="formname" type="xsd:string" />
        <xsd:element name="timestamp" type="xsd:dateTime" />
        <xsd:element name="sender" type="PersonType" minOccurs="0" />
        <xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
        <xsd:element name="signature" type="xsd:string" minOccurs="0" />
    </xsd:sequence>
</xsd:complexType> 

То, что объявляет PersonType, в основном представляет собой 12-значное число, построенное по определенному шаблону. Тип организации объявляется в основном просто десятизначным числом.

Итак, что я логично хотел бы сделать, это поставить:

<xsd:element name="sender" type="OrganizationType" minOccurs="0" />

в последовательность, но вы не можете иметь два элемента с одинаковым именем и разными типами. Поэтому я считаю, что должен решить это другим способом.

Что я нашел, так это: http://xsd.stylusstudio.com/2007Oct/post05003.htm

Это то, что я хочу сделать, но я не уверен, что это возможно. Кто-нибудь получил дальнейшие идеи о том, как решить эту проблему?

Заранее спасибо.

Ответы [ 2 ]

12 голосов
/ 20 августа 2009

Нет, вы не можете этого сделать. У вас есть возможность создать сложный тип PersonOrOrgSender, например:

  <xsd:complexType name="PersonOrOrgType">
    <xsd:choice>
      <xsd:element minOccurs="0" name="PersonSender" type="PersonType" />
      <xsd:element minOccurs="0" name="OrgSender" type="OrganizationType" />
    </xsd:choice>
  </xsd:complexType>

, а затем сделайте своего «отправителя» экземпляром этого типа:

<xsd:element name="sender" type="PersonOrOrgType" minOccurs="0" />

но тогда у вас будут XML-данные, подобные этим:

<FormInfo>
  <formname>string</formname>
  <sender>
    <OrgSender>
      <Name>string</Name>
    </OrgSender>
  </sender>  
  ...
</FormInfo>

или

<FormInfo>
  <formname>string</formname>
  <sender>
    <PersonSender>
      <Name>string</Name>
    </PersonSender>
  </sender>  
  ...
</FormInfo>

Вы не можете сделать один тег (например, «отправитель») одним и тем же в одном случае, а другой - в другом - один тег должен иметь ровно один четко определенный тип и иметь этот тип раз и навсегда.

Марк

2 голосов
/ 30 мая 2017

Учитывая ваши проблемы с решением, предоставленным @mark_s, у вас есть несколько вариантов:

  • Создайте два отдельных XSD с двумя типами для sender. В вашем коде, который запускает проверку, запускайте их последовательно (то есть человек, а затем организация). Это дает дополнительное преимущество: ваш код будет знать, какая проверка прошла (и может делать выбор на основе этих знаний).
  • Переместить выбор вверх на уровень в XSD. Внутри ForminfoType добавьте узел выбора с двумя последовательностями (один человек, одна организация). Я не подтвердил, но примерно:

    <xsd:complexType name="ForminfoType">
        <xsd:choice>
            <xsd:sequence> <!-- person -->
                <xsd:element name="formname" type="xsd:string" />
                <xsd:element name="timestamp" type="xsd:dateTime" />
                <xsd:element name="sender" type="PersonType" minOccurs="0" />
                <xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
                <xsd:element name="signature" type="xsd:string" minOccurs="0" />
            </xsd:sequence>
            <xsd:sequence> <!-- organization -->
                <xsd:element name="formname" type="xsd:string" />
                <xsd:element name="timestamp" type="xsd:dateTime" />
                <xsd:element name="sender" type="OrganizationType" minOccurs="0" />
                <xsd:element name="receiver" type="OrganizationType" minOccurs="0" />
                <xsd:element name="signature" type="xsd:string" minOccurs="0" />
            </xsd:sequence>
        </xsd:choice>
    </xsd:complexType>
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...