XSD中的xs:union怎么合并简单类型

xs:union 是 XSD 中定义值级“或”关系的简单类型组合机制,需包裹在 xs:simpleType 内,通过 memberTypes 属性列举内置或已命名的简单类型,或内联定义匿名 simpleType;不可含复杂类型、匿名复杂类型、anyType、anySimpleType 或嵌套 union,且应避免语义重叠以确保验证确定性。

xs:union 是 XSD 中用来定义“或”关系的简单类型组合机制,它不改变结构,只扩展值的合法范围——一个元素或属性只要符合其中任一成员类型,即为有效。

怎么写 union 类型定义

union 必须包裹在 xs:simpleType 内,通过 memberTypes 属性列出所有允许的类型,用空格分隔:

  • 可以是内置类型,如 xs:stringxs:integerxs:date
  • 也可以是已命名的自定义简单类型(比如用 restrictionlist 定义的)
  • memberTypes 中不能包含复杂类型,也不能写匿名类型(即不能直接在 union 里嵌套未命名的 restriction)

示例:


  

支持内联子类型定义

如果某个成员类型没有现成名字,也可以在 union 内部直接定义一个匿名 xs:simpleType

  • 适合一次性使用的约束,比如枚举字符串或带范围的数字
  • 每个内联类型必须是完整、可验证的 simpleType

示例(接受 "small"/"large" 或 1–10 的整数):


  
    
      
        
        
      
    
    
      
        
        
      
    
  

怎么用 union 类型

定义完后,像普通类型一样用于 xs:elementxs:attribute

  • 用于元素时,内容必须严格匹配其中一个成员类型(如 5large
  • 用于属性时,值也需满足 union 中任一类型(如 size="small"size="7"
  • 注意:XML 解析器会根据实际值自动选择最匹配的成员类型,但不会做隐式转换(例如 "123" 不会自动当整数,除非 string 和 integer 同时存在且无歧义)

要注意的几个关键点

union 看似简单,但容易踩坑:

  • 避免语义重叠:比如同时包含 xs:stringxs:integer,会导致 "42" 既可当字符串也可当整数,XSD 验证器可能无法唯一判定,引发不确定行为
  • 不等价于 xs:choice:choice 是结构级“多选一”,需要不同子元素;union 是值级“多选一”,作用于纯文本内容,更轻量
  • 不支持 anyType 或 anySimpleType 作为 memberTypes:union 要求每个成员都明确、可静态验证
  • 不能嵌套 union:memberTypes 只接受类型名或内联 simpleType,不能写另一个 union 元素

基本上就这些。