Требуется установить свойство xsd в соответствии со значением перечисления
У меня есть следующий xsd для моего проекта. Я пытаюсь создать один xsd для xmls ACH и CC на основе атрибута enum Payment Method, если метод оплаты Ach, тогда требуется ACHInfo, иначе CreditCardInfo..
<xs:element name="PaymentMethod">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="ACH"/>
<xs:enumeration value="CreditCard"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CreditCardInfo" minOccurs="0">
<xs:complexType>
<xs:all>
<xs:element name="Cvv2No">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="CardNumber">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="20"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="ACHInfo" minOccurs="0">
<xs:complexType>
<xs:all>
<xs:element name="RoutingNumber" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="AccountNumber" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
Может ли кто-нибудь дать мне решение для этого, какие изменения требуются в xsd, чтобы сделать свойство требуемым в соответствии со значением enum
Благодарю.
1 ответ
Четыре решения, некоторые из которых включают переосмысление представления вашей информации в формате XML:
Утверждение XSD 1.1
Самый простой способ сделать то, что вы описываете, это использовать XSD 1.1 и определить ограничение, которое вы имеете в виду, с помощью утверждения. Вы не говорите, как называется родительский элемент; Я назову это Оплата. И я буду использовать префикс tns
для целевого пространства имен.
<xs:element name="Payment">
<xs:complexType>
<xs:sequence>
<xs:element ref="tns:PaymentMethod"/>
<xs:choice>
<xs:element ref="tns:ACHInfo" minOccurs="0"/>
<xs:element ref="tns:CreditCardInfo" minOccurs="0"/>
</xs:choice>
</xs:sequence>
<xs:assert test="(tns:PaymentType = 'ACH' and ./tns:ACHInfo)
or
(tns:PaymentType = 'CreditCard'
and ./tns:CreditCardInfo)"/>
</xs:complexType>
</xs:element>
Условное присвоение типов XSD 1.1
Для некоторых целей лучше использовать условное присвоение типа (также функция 1.1) для Платежа. По техническим причинам это означает, что PaymentType должен быть атрибутом Payment, а не дочерним элементом:
<xs:element name="Payment">
<xs:alternative test="@PaymentMethod='ACH'"
type="tns:ACHPayment"/>
<xs:alternative test="@PaymentMethod='CreditCard'"
type="tns:CCPayment"/>
<xs:alternative type="xs:error"/>
</xs:element>
Это объявление означает: если значение атрибута PaymentMethod равно "ACH", тогда элемент Payment имеет тип tns:ACHPayment (который мы определим чуть позже). В противном случае, если значением PaymentMethod является "CreditCard", то типом оплаты будет tns: CCPayment. В противном случае элемент недействителен.
Мы объявляем именованные типы ACHPayment и CCPayment как содержащие соответствующие дочерние элементы (а также предоставляя атрибут PaymentMethod) - мы можем встроить их, но присвоение им имен упрощает просмотр шаблона назначения условных типов:
<xs:complexType name="ACHPayment">
<xs:sequence>
<xs:element ref="tns:ACHPayment"/>
</xs:sequence>
<xs:attribute name="PaymentMethod" type="tns:PaymentMethod"/>
</xs:complexType>
<xs:complexType name="CCPayment">
<xs:sequence>
<xs:element ref="tns:CreditCardPayment"/>
</xs:sequence>
<xs:attribute name="PaymentMethod" type="tns:PaymentMethod"/>
</xs:complexType>
И по той же причине мы предоставляем именованное объявление для типа атрибута PaymentMethod:
<xs:simpleType name="PaymentMethod">
<xs:restriction base="xs:string">
<xs:enumeration value="ACH"/>
<xs:enumeration value="CreditCard"/>
</xs:restriction>
</xs:simpleType>
XSD 1.0, перемещение метода оплаты в модель контента
Но вам не нужен XSD 1.1 для создания XML, который работает для вашего приложения; вам просто нужно по-другому думать о вашем дизайне. Легко сделать ACHinfo обязательной для платежей ACH и CreditCardInfo необходимой для платежей кредитной картой, если вы выбираете тип платежа в названии элемента, а не в содержании. Вместо определения родительского типа как:
<xs:complexType>
<xs:sequence>
<xs:element ref="tns:PaymentMethod"/>
<xs:element ref="CreditCardInfo" minOccurs="0"/>
<xs:element ref="ACHInfo" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
Вы могли бы объявить это так:
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element ref="tns:ACHPayment"/>
<xs:element ref="tns:ACHInfo" minOccurs="0"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="tns:CCPayment"/>
<xs:element ref="tns:CreditCardInfo" minOccurs="0"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
Два элемента флага CCPayment и ACHPayment могут быть пустыми элементами:
<xs:complexType name="EMPTY">
<xs:sequence/>
</xs:complexType>
<xs:element name='ACHPayment' type="tns:EMPTY"/>
<xs:element name='CCPayment' type="tns:EMPTY"/>
Но, поскольку вещи стоят, ни один из них не делает никакой работы в дизайне.
XSD 1.0, упрощение
Если ни элемент ACHPayment, ни элемент CCPayment не выполняют никакой работы, кроме (а) сигнализации о том, что платеж использует этот метод и (б) обеспечения правильности следующего брата, то ни один из них не выполняет никакой работы вообще.,
Вы также можете легко определить родительский элемент следующим образом:
<xs:element name="Payment">
<xs:complexType>
<xs:choice>
<xs:element ref="tns:ACHInfo" minOccurs="0"/>
<xs:element ref="tns:CreditCardInfo" minOccurs="0"/>
</xs:choice>
</xs:complexType>
</xs:element>
Вы по-прежнему можете видеть, является ли платеж ACH-платежом (дочерний элемент элемента оплаты называется ACHInfo) или платежом по кредитной карте (дочерний элемент называется CreditCardInfo), и вам больше не нужно проверять, чтобы подробная информация соответствовала флаг PaymentMethod, потому что флаг PaymentMethod исчез.
Меньше движущихся частей, меньше делать, меньше идти не так.
Из этих четырех дизайнов я думаю, что четвертый, вероятно, лучший. Ваш пробег, конечно, может отличаться.