不能真正重定义类型,仅能在未被引用前有限扩展枚举或调整occurs;它受限严格、工具支持差、行为不一致,应避免使用。

什么是 <redefine></redefine>,它真能重定义类型吗
<redefine></redefine> 在 XSD 1.0 中名义上用于“重新定义”来自外部 schema 的简单/复杂类型、组或属性组,但实际效果非常受限:它只能在被 redefine 的类型**未被使用前**做有限修改,比如扩展 simpleType 的枚举值、调整 minOccurs/maxOccurs(仅当原定义是 group 或 attributeGroup),而不能改变结构、基类型或删除已有成员。多数现代工具(如 Xerces、libxml2)对 <redefine></redefine> 支持不完整,甚至直接忽略或报错。
<redefine></redefine> 的典型写法和关键约束
必须满足三个硬性条件,缺一不可:
-
<redefine></redefine>必须作为<schema></schema>的直接子元素,且其schemaLocation属性指向一个**已通过<include></include>或<import></import>引入**的外部 XSD 文件 - 被 redefine 的类型在当前 schema 中**尚未被任何元素、属性或类型引用**(否则解析器会拒绝)
- redefine 内部只能包含与原定义同名的
<simpletype></simpletype>、<complextype></complextype>、<group></group>或<attributegroup></attributegroup>,且不能改变其种类(例如不能用<complextype></complextype>去 redefine 一个<simpletype></simpletype>)
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<include schemaLocation="base.xsd"/>
<redefine schemaLocation="base.xsd">
<simpleType name="status">
<restriction base="string">
<enumeration value="active"/>
<enumeration value="inactive"/>
<enumeration value="pending"/> <!-- 新增值 -->
</restriction>
</simpleType>
</redefine>
</schema>为什么你大概率不该用 <redefine></redefine>
几乎所有真实场景下,<redefine></redefine> 都不如替代方案可靠:
- 想扩展枚举?改用
union或新simpleType+<assert></assert>(XSD 1.1) - 想复用并微调结构?用
<extension></extension>或<restriction></restriction>定义新类型,再<import></import>使用 - 需要模块化演进?靠版本化命名(
Order_v2.xsd)+<import></import>显式依赖,比 redefine 更可控 - 主流验证器(如 Saxon-EE 支持 XSD 1.1)已弃用 redefine;Java JAXB、.NET XmlSchemaSet 默认禁用或静默失败
XSD 1.1 的 <override></override> 能替代吗
不能直接替代。XSD 1.1 引入了 <override></override>,但它和 <redefine></redefine> 是正交机制:<override></override> 允许完全替换导入的类型定义(包括结构变更),但要求整个 schema 集合启用 XSD 1.1 模式,且所有工具链(解析器、IDE、生成器)必须支持。实践中,<override></override> 的兼容性比 <redefine></redefine> 更差——多数 XML 编辑器和构建插件仍只认 XSD 1.0。
真正容易被忽略的是:哪怕语法合法,<redefine></redefine> 的行为在不同处理器间差异极大。一个在 Oxygen XML 中能验证通过的 redefine,在 Python 的 lxml 里可能抛出 LxmlError: redefine not supported,而在 Java 的 SchemaFactory 中可能静默跳过。别把它当可移植特性用。


















