Xsd тот же самый элемент, разные типы?
У меня есть ситуация, когда элемент в 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-значное число, построенное по определенному шаблону. То, что объявляет тип организации, представляет собой просто 10-значное число.
Так что я логически хотел бы сделать это:
<xsd:element name="sender" type="OrganizationType" minOccurs="0" />
в последовательность, но вы не можете иметь два элемента с одинаковым именем и разными типами. Поэтому я считаю, что я должен решить это каким-то другим способом.
Я нашел следующее:
http://xsd.stylusstudio.com/2007Oct/post05003.htm
Это в значительной степени то, что я хочу сделать, но я не уверен, что это возможно.
Кто-нибудь получил какие-либо дальнейшие идеи о том, как это решить?
Спасибо заранее.
Ответы
Ответ 1
Нет, вы не можете этого сделать. Один из вариантов заключается в создании сложного типа "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
Учитывая ваши проблемы с решением, предоставленным @mark_s, у вас есть несколько вариантов:
- Создайте два отдельных XSD с двумя типами для
sender
. В коде, который запускает проверку, запускайте их последовательно (например, человек, затем организация). Это имеет дополнительное преимущество в том, что ваш код будет знать, какая проверка прошла (и может делать выбор на основе этих знаний).
-
Переместите выбор до уровня в XSD. Внутри ForminfoType
добавьте выбор node с двумя последовательностями (один человек, одна организация). Я не проверял, но грубо:
<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>