有些人可能会说:如果你可以编辑两个XSD,为什么还要重新定义?
我将向您展示如何使用XSD重定义工作,至少从XSD角度来看。但是,由于JAXB的局限性,它不适用于开箱即用。如果您还使用自动XSD重构,作为额外的步骤,那么您可以使其工作,并且在此过程中,您将保留使用xsd:redefine时看到的价值主张。因此,在此之前,这里是另一种也使用组合的方式,但没有xsd:redefine
;从维护和验证的角度来看,您正在获得相同的价值和用法。
我将第一个XSD称为Model1
,第二个XSD称为Model2
。我将从一个XSD开始,它将为您提供xs:redefine
中的“通过组合重用”方面。
共同项目,XSD的允许扩展,兼容性强和验证,共items.xsd:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:group name="typeA">
<xs:sequence>
<xs:element name="elA" type="xs:string" />
</xs:sequence>
</xs:group>
<xs:element name="root" type="typeA" />
</xs:schema>
型号1“项目”,XSD的允许扩展,兼容性强,和 - 验证,模型1项。XSD:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:complexType name="typeA">
<xs:sequence>
<xs:group ref="typeA" />
<xs:any namespace="##any" minOccurs="0" processContents="lax" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Model2的 “项目”,XSD的允许扩展,兼容性强和验证,模型2-items.xsd:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:complexType name="typeA">
<xs:sequence>
<xs:group ref="typeA" />
<xs:element name="newElement" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
如果你通过通用项目和型号1,或通用项目和Model2到JAXB编译器,它将以您想要的方式创建类。为了方便使用(测试)和插图,我创建了两个以上的XSD:
型号1:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-common-items.xsd"/>
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-model1-items.xsd"/>
</xs:schema>
模型2:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-common-items.xsd"/>
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-model2-items.xsd"/>
</xs:schema>
这是当你运行XJC agains你会得到什么型号1:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "typeA", propOrder = {
"elA",
"any"
})
public class TypeA {
@XmlElement(required = true)
protected String elA;
@XmlAnyElement(lax = true)
protected Object any;
/**
* Gets the value of the elA property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getElA() {
return elA;
}
/**
* Sets the value of the elA property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setElA(String value) {
this.elA = value;
}
/**
* Gets the value of the any property.
*
* @return
* possible object is
* {@link Element }
* {@link Object }
*
*/
public Object getAny() {
return any;
}
/**
* Sets the value of the any property.
*
* @param value
* allowed object is
* {@link Element }
* {@link Object }
*
*/
public void setAny(Object value) {
this.any = value;
}
}
...当你运行XJC agains模型2:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "typeA", propOrder = {
"elA",
"newElement"
})
public class TypeA {
@XmlElement(required = true)
protected String elA;
@XmlElement(required = true)
protected String newElement;
/**
* Gets the value of the elA property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getElA() {
return elA;
}
/**
* Sets the value of the elA property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setElA(String value) {
this.elA = value;
}
/**
* Gets the value of the newElement property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getNewElement() {
return newElement;
}
/**
* Sets the value of the newElement property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setNewElement(String value) {
this.newElement = value;
}
}
Model1和Model2 XSD将按照您预期的方式验证您的XML。
下面的图表显示了XSD文件之间的关系。绿色表示“xsd:include”,箭头指向“包含”。

更新:我刚刚注意到,根据@Kevin的评论,你没有的maxOccurs在重新定义的新元素。在这种情况下,你可以使用一个单一的重新定义,像这样:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="example" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:redefine schemaLocation="xsd-allow-extension-compatibility-and-validation.xsd">
<xsd:complexType name="typeA">
<xsd:complexContent>
<xsd:restriction base="typeA">
<xsd:sequence>
<xsd:element name="elA" type="xsd:string" />
<xsd:element name="newElement" type="xsd:string" />
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>
</xsd:schema>
唯一的问题似乎是,JAXB(最新)仍然使用通配符生成的类。
更新2:基于Kevin的评论,两个避免两个重新定义,应该使用一个组而不是xsd:any。
如果您实际上计划使用多个元素来扩展新模型,请继续阅读。下面是这样做的唯一方法,这需要使用一组来进一步细化任何粒子。
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="example" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:redefine schemaLocation="xsd-allow-extension-compatibility-and-validation.xsd">
<xsd:complexType name="typeA">
<xsd:complexContent>
<xsd:restriction base="typeA">
<xsd:sequence>
<xsd:element name="elA" type="xsd:string" />
<xsd:group ref="group1" minOccurs="0">
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>
<xsd:group name="group1">
<xsd:sequence>
<xsd:element name="newElement" type="xsd:string" />
</xsd:sequence>
</xsd:group>
</xsd:schema>
最终的结果是,新的XSD可以用来验证模型1,而原来的文件保持模型1。
元素粒子可以是任何通配符的有效限制。我认为你不应该需要使用两个重新定义,而只需要你进行限制。换句话说,将元素声明代替限制中的xsd:any。 – Kevin
正确。但是,只有当你添加**一个**元素时,它才能工作。因此,上述工作适用于任何你希望扩展它的方式,并且仍然符合** xsd:any **的初始意图(我刚才意识到他没有使用maxOccurs =“unbounded”,这是我认为理所当然的)。 –
@PetruGardea谢谢,这正是我需要的。 – rmillet