根据枚举值设置所需的 xsd 属性 [英] xsd property set required according to enum value

查看:19
本文介绍了根据枚举值设置所需的 xsd 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目有以下 xsd 我正在尝试根据 Payment Method 枚举属性为 xmls ACH 和 CC 制作单个 xsd 如果付款方式是 Ach,则需要 ACHInfo 否则 CreditCardInfo ..

I have following xsd for my project I am trying to make single xsd for both xmls ACH and CC on basis of Payment Method enum attribute if payment method is Ach then ACHInfo becomes required else 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 需要根据枚举值进行哪些更改以使属性成为必需.

can any one give me solution for this what changes required in xsd to make property required according to enum value.

谢谢.

推荐答案

四个解决方案,其中一些涉及重新考虑您的信息的 XML 表示:

Four solutions, some of which involve re-thinking the XML representation of your information:

实现您所描述的最简单的方法是使用 XSD 1.1 并使用断言定义您想到的约束.你不说父元素叫什么;我称之为付款.我将使用前缀 tns 作为目标命名空间.

The easiest way to do just what you describe is to use XSD 1.1 and define the constraint you have in mind with an assertion. You don't say what the parent element is called; I'll call it Payment. And I'll use the prefix tns for the target namespace.

<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 的属性,而不是子属性:

XSD 1.1 conditional type assignment

A better way, for some purposes, would be to use conditional type assignment (also a 1.1 feature) for Payment. For technical reasons, that entails making PaymentType an attribute on Payment, not a child:

<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",则 Payment 类型为 tns:CCPayment.否则,该元素无效.

This declaration means: if the value of the PaymentMethod attribute is "ACH" then element Payment has type tns:ACHPayment (which we'll define in a moment). Otherwise if the value of PaymentMethod is "CreditCard" then the type of Payment is tns:CCPayment. Otherwise, the element is invalid.

我们将命名类型 ACHPayment 和 CCPayment 声明为包含适当的子级(并提供 PaymentMethod 属性)——我们可以内联它们,但命名它们会使条件类型分配模式更容易看到:

We declare the named types ACHPayment and CCPayment as containing the appropriate children (and also providing for the PaymentMethod attribute) -- we could inline them, but naming them make the conditional type assignment pattern easier to see:

<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 属性的类型提供了一个命名声明:

And for the same reason, we provide a named declaration for the type of the PaymentMethod attribute:

<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;您只需要对您的设计进行不同的思考.如果您在元素名称中而不是在内容中选择付款类型,则很容易使 ACH 付款需要 ACHinfo 和信用卡付款需要 CreditCardInfo.而不是将父类型定义为:

XSD 1.0, moving payment method into the content model

But you don't need XSD 1.1 to make XML that works for your application; you just need to think differently about your design. It's easy to make ACHinfo required for ACH payments and CreditCardInfo required for credit-card payments, if you carry the choice of payment type in the name of an element instead of in content. Instead of defining the parent type as:

<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 可以是空元素:

The two flag elements CCPayment and ACHPayment can be empty elements:

<xs:complexType name="EMPTY">
  <xs:sequence/>
</xs:complexType>

<xs:element name='ACHPayment' type="tns:EMPTY"/>
<xs:element name='CCPayment' type="tns:EMPTY"/>

但就目前的情况而言,这些都没有在设计中做任何工作.

But as things stand neither of these is doing any work in the design.

如果 ACHPayment 和 CCPayment 元素都没有做任何工作,除了 (a) 表明付款使用这种方法,以及 (b) 确保下面的兄弟是正确的,那么他们都没有做任何事情工作.

If neither the ACHPayment nor the CCPayment element is doing any work beyond (a) signaling that the payment uses this method of that, and (b) ensuring that the following sibling is the correct one, then neither of them is doing any work at all.

您可以通过这种方式轻松定义父元素:

You could just as easily define the parent element this way:

<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 付款(Payment 元素的子元素名为 ACHInfo)还是信用卡付款(子元素名为 CreditCardInfo),您不再需要检查以确保详细信息与 PaymentMethod 标志一致,因为 PaymentMethod 标志已经消失.

You can still see whether the payment is an ACH payment (the Payment element's child is named ACHInfo) or a credit-card payment (the child is named CreditCardInfo), and you no longer have to check to make sure the detail information is consistent with the PaymentMethod flag, because the PaymentMethod flag has gone away.

更少的活动部件,更少的事情,更少的错误.

Fewer moving parts, less to do, less to go wrong.

在这四种设计中,我认为这第四种可能是最好的.当然,您的里程可能会有所不同.

Of these four designs, I think this fourth one is probably the best. Your mileage, of course, may vary.

这篇关于根据枚举值设置所需的 xsd 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆