【问题标题】:XSD condition based on element value基于元素值的 XSD 条件
【发布时间】:2012-09-11 20:41:15
【问题描述】:

我有一个对象有 3 个属性: 1) 动作 2) 身份证 3) 名称

Action 可以是 Update 或 Remove 并且是强制性的。 ID 是一个 int 并且是强制性的。 name 是一个字符串,在Action=Remove 时是可选的,在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>

【问题讨论】:

  • 根据我的经验,您不使用 XSD 来定义元素的情况,而只是定义元素/属性应该相互关联的方式,而不管它们的值如何。因此,如果您遇到根据某些情况需要 3 个属性/元素是可选/必需的情况,您需要针对这些独特情况进行设计。

标签: .net xml vb.net xsd


【解决方案1】:

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

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

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

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

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

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

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

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

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

<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 的类型声明为限制那种。这会使这个例子变得更长更乏味,所以我满足于在这里提及它。这是否有意义取决于您对维护架构的人的信任程度,以及您的其他架构感知工具是否会利用这些信息做有用的事情。

【讨论】:

  • 我根本不擅长 XSD。您介意根据我上面的示例给我一个 XSD 示例吗?谢谢
  • 喜欢你的解释!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多