有些人可能會說:如果你可以編輯兩個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