【问题标题】:Choice of attributeGroup属性组的选择
【发布时间】:2015-04-13 14:26:33
【问题描述】:

问题

我必须选择性地向现有的 Value 元素添加一组属性(见下文)。此元素不得包含一组以上的属性(见下文)。

注意:unit 属性不包含在属性集中。

Value元素的声明:

<xs:element name="Value">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="unit" use="required" type="xs:string" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

声明我的两个attributeGroup

<xs:attributeGroup name="setOfAttrs1">
    <xs:attribute name= "a" type="xs:int" use="required" />
    <xs:attribute name="b" type="xs:int" use="required" />
    <xs:attribute name="c" type="xs:int" use="required" />
</xs:attributeGroup>
<xs:attributeGroup name="setOfAttrs2">
    <xs:attribute name= "x" type="xs:int" use="required" />
    <xs:attribute name="y" type="xs:int" use="required" />
    <xs:attribute name="z" type="xs:int" use="required" />
</xs:attributeGroup>

正确示例(针对模式)

<Value unit="m3">i'm correct</value>
<Value unit="m3" x="1" y="1" z="0">i'm correct</value>
<Value unit="m3" a="1" b="1" c="0">i'm correct</value>

不正确的示例(针对架构)

第一个错过了z属性;第二个包含两组属性。

<Value unit="m3" x="1" y="1">i'm incorrect</value>
<Value unit="m3" x="1" y="1" z="0" a="0" b="1" c="0">i'm incorrect</value>

尝试过的解决方案

<xs:element name="Value">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="PhysicalUnit" use="required" type="xs:string" />
                <xs:choice minOccurs="0" maxOccurs="1">
                    <xs:attributeGroup ref="setOfAttrs1" />
                    <xs:attributeGroup ref="setOfAttrs2" />
                </xs:choice>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
</xs:element>

但这不是一个有效的 XSD:

错误 - 第 93、45 行:org.xml.sax.SAXParseException;行号:93; 列号:45; s4s-elt-invalid-content.1:内容 “#AnonType_Value”无效。元素“选择”无效、错位、 或发生得太频繁。

有人知道如何解决这个问题吗?

【问题讨论】:

  • XSD 1.0 不可能 - xs:choice 中不允许使用属性。要么使用 XSD 1.1 断言,要么将 elements 放入 xs:choice,并使属性集成为元素之间的唯一区别 - 例如 deriving two actual types from an abstract type
  • @MathiasMüller 是正确的,这不能在 XSD 1.0 中表达。请参阅我的answer below,了解如何在 XSD 1.1 中使用断言。

标签: xml xsd


【解决方案1】:

您不能在 XSD 1.0 中表达这样的约束。

在 XSD 1.1 中,您可以将属性设为可选,并通过 xs:assert 表达您的复杂需求约束。您希望允许以下三种情况:

  1. 所有 a、b 和 c,但没有 x、y、z:

    @a and @b and @c and not(@x) and not(@y) and not(@z)

  2. a、b 和 c 都不是,但 x、y、z 都是:

    not(@a) and not(@b) and not(@c) and @x and @y and @z

  3. a、b、c、x、y、z 都不是:

    not(@a or @b or @c or @x or @y or @z)

XSD 1.1

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" 
  elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
  vc:minVersion="1.1">

  <xs:element name="Value">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="unit" use="required" type="xs:string" />
          <xs:attributeGroup ref="setOfAttrs1" />
          <xs:attributeGroup ref="setOfAttrs2" />
          <xs:assert test="(@a and @b and @c and not(@x) and not(@y) and not(@z)) 
                            or (not(@a) and not(@b) and not(@c) and @x and @y and @z) 
                            or not(@a or @b or @c or @x or @y or @z)"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:attributeGroup name="setOfAttrs1">
    <xs:attribute name="a" type="xs:int"/>
    <xs:attribute name="b" type="xs:int"/>
    <xs:attribute name="c" type="xs:int" />
  </xs:attributeGroup>

  <xs:attributeGroup name="setOfAttrs2">
    <xs:attribute name="x" type="xs:int"/>
    <xs:attribute name="y" type="xs:int" />
    <xs:attribute name="z" type="xs:int"/>
  </xs:attributeGroup>

</xs:schema>

【讨论】:

    【解决方案2】:

    在 XSD 1.1 中执行此操作的另一种方法是使用条件类型分配。这里定义了两种类型,其中一种具有属性 a/b/c,另一种具有属性 x/y/z,并通过条件测试在这两种类型之间进行选择:

    <xs:element name="Value" type="ValueType">
      <xs:alternative test="@a" type="ValueTypeWithABC"/> 
      <xs:alternative           type="ValueTypeWithXYZ"/>
    </xs:element>
    

    【讨论】:

      猜你喜欢
      • 2017-10-05
      • 1970-01-01
      • 2010-10-19
      • 2015-06-21
      • 1970-01-01
      • 2022-11-19
      • 1970-01-01
      • 2011-09-08
      相关资源
      最近更新 更多