使用XSD在XML键值列表中约束值

时间:2011-09-05 15:49:46

标签: xml xsd xsd-validation

我有一个XML文档(基本上)如下所示:

...
<param>
    <key>age</key>
    <value>10</value>
</param>
<param>
    <key>smart</key>
    <value>true</value>
</param>
...

我想基于参数键限制可用值,例如age应该是[0,150]中的整数,smart应该是true或false。

现在,如果XML不同(例如,如下例所示),那将非常简单:

...
<age>10</age>
<smart>true</smart>
...

但是,XML结构在这一点上不会改变,我不确定它应该如何。有没有办法用当前的XML结构实现这些类型的约束,如果有,怎么做?

更新:

根据(完全没有)反馈来判断,我认为使用XSD可能无法做到这一点。有人可以证实吗?

1 个答案:

答案 0 :(得分:1)

看起来你几乎需要一个看起来像这样的定义:

  <!-- This is an INVALID example -->
  <xs:element name="param">
    <xs:complexType>
      <xs:choice>
        <xs:sequence>
          <xs:element name="key" type="xs:string" fixed="age" />
          <xs:element name="value" type="xs:decimal" />
        </xs:sequence>
        <xs:sequence>
          <xs:element name="key" type="xs:string" fixed="smart" />
          <xs:element name="value" type="xs:boolean" />
        </xs:sequence>
      </xs:choice>
    </xs:complexType>
  </xs:element>

不幸的是,这段代码会导致无效的XML Schema 文件。

虽然语法正确,但语义违反了架构规则。具有相同名称且在相同范围内的元素必须具有相同的类型。在这种情况下,它尤其意味着作为<value>元素的子元素的所有<param>元素必须具有相同的类型。

形式上这是Schema Component Constraint: Element Declarations Consistent。另请参见以下架构组件约束;通常,您不能使元素类型依赖于文档中的某些其他值或有关序列其余部分中的项的任何信息。

更新

我完全忘记了这一点,但是如果您在实例文档中指定了所需类型而不是纯粹在架构中定义它,那么您应该能够获得所需的约束。这可以通过将xsi:type属性添加到<value>元素来完成。

实施例

<param>
    <key>age</key>
    <value xsi:type="xs:decimal">10</value>
</param>
<param>
    <key>smart</key>
    <value xsi:type="xs:boolean">true</value>
</param>

当然这有点不方便,因为它需要更改XML生成过程。此外,它不会自动保证<key>和定义的xsi:type是匹配对。