Jaxb XSD允许扩展、兼容性和验证

Jaxb XSD允许扩展、兼容性和验证,jaxb,xsd,Jaxb,Xsd,我想为一个应用程序创建一个XSD,并扩展另一个XSD(仅通过添加元素) 我希望第二个应用程序生成的XML文件与第一个应用程序有效 我试过这个: 第一个XSD: 第二个XSD: 必须对第一个XSD(但不是第二个)有效的XML示例: MyString 必须与两者都有效的XML示例 MyString 我的新闻字符串 前面的XSD违反了“唯一粒子属性”,我希望这是固定的。 我可以编辑两个XSD,但我希望能够在完成第二个XSD之前分发第一个XSD 我如何才能做到这一点(当JAXB检查时,

我想为一个应用程序创建一个XSD,并扩展另一个XSD(仅通过添加元素)

我希望第二个应用程序生成的XML文件与第一个应用程序有效

我试过这个:

第一个XSD:


第二个XSD:


必须对第一个XSD(但不是第二个)有效的XML示例:


MyString
必须与两者都有效的XML示例


MyString
我的新闻字符串
前面的XSD违反了“唯一粒子属性”,我希望这是固定的。 我可以编辑两个XSD,但我希望能够在完成第二个XSD之前分发第一个XSD

我如何才能做到这一点(当JAXB检查时,两种模式都必须有效)


谢谢

你真正想要的是一个限制。进行扩展时,通配符仍然是内容模型的一部分,这就是为什么存在唯一的粒子属性冲突。实际上,您要做的是将通配符替换为限制性更强的元素。

有些人可能会说:如果您可以编辑两个XSD,为什么还要重新定义

我将向您展示如何使用XSD重新定义,至少从XSD的角度来看是这样。然而,考虑到JAXB的局限性,它无法开箱即用。如果您还使用自动XSD重构作为额外的步骤,那么您可以让它工作,并且在这个过程中,您将保留使用XSD:redefinite时看到的价值主张

因此,在此之前,这里还有另一种方法,它也使用组合,但不使用xsd:redefinite;从维护和验证的角度来看,您得到的价值和使用率大致相同

我将第一个XSD称为
Model1
,第二个XSD称为
Model2
。我将从一个XSD开始,它将为您提供
xs:redefinite
的“通过组合重用”特性

公共项,xsd允许扩展兼容性和验证公共项。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> 
<?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> 
<?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> 
。。。当您再次运行xjc Model2时:

@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和model2xsd将按照您预期的方式验证您的xml

下图显示了XSD文件之间的关系。绿色表示“xsd:include”,箭头指向“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可以用于验证Model1,而原始文件仍然是Model1

元素粒子可以是任意通配符的有效限制。我认为不需要使用两个重定义,只需要使用一个进行限制的重定义。换句话说,将元素声明替换restriction.Correct中的xsd:any。但是,只有当您添加一个元素时,它才会起作用。因此,以上内容适用于任何您希望扩展它的方式,并且仍然符合xsd:any的初始意图(我刚刚意识到他没有使用maxOccurs=“unbounded”,这是我认为理所当然的)。@PetruGardea谢谢,这正是我需要的。@PertruGardea True。如果xsd:any重复,并且您想用许多元素替换它,那么您将使用序列组。序列组可以是任意通配符的有效限制。@凯文,你说得对(++1),你今天教了我一些东西。非常感谢。
@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;
    }

}
<?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>
<?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>