2

我的对象有 3 个属性:1) 操作 2) ID 3) 名称

Action可以是UpdateRemove并且是强制性的。ID是一个 int 并且是强制性的。Name 是一个字符串,并且是可选的 whenAction=Remove并且是强制的 when Action=Update

我如何在 XSD 中描述这一点?谢谢!

吉姆

这是我到目前为止所拥有的:

   <s:element name="UpdateAccount">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="myAccount" type="tns:WSUpdate" />
      </s:sequence>
    </s:complexType>
  </s:element>
  <s:complexType name="WSUpdate">
    <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="ID" type="s:int" />
      <s:element minOccurs="1" maxOccurs="1" name="Name" nillable="false" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="action" type="tns:UpdateAction" />
    </s:sequence>
  </s:complexType>
  <s:simpleType name="UpdateAction">
    <s:restriction base="s:string">
      <s:enumeration value="Update" />
      <s:enumeration value="Remove" />
    </s:restriction>
  </s:simpleType>

编辑 2012 年 9 月 12 日 @ 美国东部标准时间上午 9:28: 在做了更多思考之后,我已经修补了一些东西。这不是我想要的,但可能足够接近我的客户接受。它并没有完全进入条件细节,但它确实为客户提供了结构定义。你怎么看?

  <s:element name="UpdateAccount">
    <s:complexType>
      <s:sequence>
        <s:choice>
    <s:element minOccurs="0" maxOccurs="1" name="myAccount" type="tns:WSUpdate" />
    <s:element minOccurs="0" maxOccurs="1" name="myAccount" type="tns:WSDelete" />
    </s:choice>
      </s:sequence>
    </s:complexType>
  </s:element>
  <s:complexType name="WSUpdate">
    <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="ID" type="s:int" />
      <s:element minOccurs="1" maxOccurs="1" name="Name" nillable="false" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="action" type="tns:UpdateAction" />
    </s:sequence>
  </s:complexType>
  <s:complexType name="WSDelete">
    <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="ID" type="s:int" />
      <s:element minOccurs="0" maxOccurs="1" name="Name" nillable="true" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="action" type="tns:UpdateAction" />
    </s:sequence>
  </s:complexType>
  <s:simpleType name="UpdateAction">
    <s:restriction base="s:string">
      <s:enumeration value="Update" />
      <s:enumeration value="Remove" />
    </s:restriction>
  </s:simpleType>
4

2 回答 2

3

在 XSD 1.0 中解决问题的一种简单方法是稍微改变问题的术语:用WSUpdate同名的抽象元素替换当前元素;定义UpdateRemove可以替代它的元素。根据需要将属性声明为可选或Update必需Remove

在 XSD 1.0 中检查此类条件所需的只是条件取决于元素名称,而不是元素的其他属性。

[2012 年 9 月 12 日编辑:OP 要求提供更完整的示例。]

这是一个使用抽象元素的简单示例。

首先,我们让UpdateAccounttype 引用它的子元素,而不是在本地声明它。这允许其他元素也可以引用它,并声明自己可以替代它。

<xs:element name="UpdateAccount">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" 
                  ref="tns:myAccount" />
    </xs:sequence>
  </xs:complexType>
</xs:element>

然后我们将myAccount元素本身声明为抽象元素。不接受实际命名的元素myAccount,只接受声明为可替代的具体元素myAccount

<xs:element name="myAccount" abstract="true"/>

然后我们声明两个可替代的具体元素myAccount,并为它们提供具有适当约束的类型。action不再需要子元素:删除和更新之间的区别现在由元素的名称(vs updateremove给出。

<xs:element name="update" type="tns:WSUpdate" 
            substitutionGroup="tns:myAccount"/>
<xs:complexType name="WSUpdate">
  <xs:sequence>
    <xs:element minOccurs="1" maxOccurs="1" 
                name="ID" type="xs:int" />
    <xs:element minOccurs="1" maxOccurs="1" 
                name="Name" nillable="false" type="xs:string" />
  </xs:sequence>
</xs:complexType>

<xs:element name="remove" type="tns:WSDelete" 
            substitutionGroup="tns:myAccount"/>
<xs:complexType name="WSDelete">
  <xs:sequence>
    <xs:element minOccurs="1" maxOccurs="1" 
                name="ID" type="xs:int" />
    <xs:element minOccurs="0" maxOccurs="1" 
                name="Name" 
                nillable="false" type="xs:string" />
  </xs:sequence>
</xs:complexType>

在某些情况下,可能需要将元素声明myAccount为具有命名类型(如tns:WSUpdate原始示例中的 )并将类型声明为该类型的update限制remove。这会使这个例子变得更长更乏味,所以我满足于在这里提及它。这是否有意义取决于您对维护模式的人的信任程度以及您的其他模式感知工具是否会对信息做有用的事情。

于 2012-09-12T23:22:44.540 回答
1

您描述的情况,其中一个属性的规则取决于另一个属性的值,通常被称为“共现约束”,并且在 XSD 1.0 中没有办法做到这一点。XSD 1.1 完全支持它使用一种称为“条件类型分配”的机制,但要使用它,您需要采用 Saxon 或 Xerces 作为您的 XSD 验证器。

于 2012-09-11T23:16:36.930 回答