3

あるアプリケーション用の XSD と、最初のアプリケーションを拡張する別の XSD を作成したいと考えています (要素を追加することによってのみ)。

2 番目のアプリケーションによって生成された XML ファイルが、最初のアプリケーションでも有効になるようにしたいと考えています。

私はこれを試しました:

最初の XSD:

<?xml version="1.0" encoding="UTF-8" ?>
<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:element name="elA" type="xs:string" />
      <xs:any namespace="##any" minOccurs="0" processContents="lax" />
    </xs:sequence>
  </xs:complexType>

  <xs:element name="root" type="typeA" />
</xs:schema>

2 番目の XSD:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns="example"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       targetNamespace="example">
  <xs:redefine schemaLocation="firstXSD.xsd">
    <xs:complexType name="typeA">
      <xs:complexContent>
       <xs:extension base="typeA">
         <xs:sequence>
           <xs:element name="newElement" type="xs:string" />
         </xs:sequence>
       </xs:extension>
      </xs:complexContent>
    </xs:complexType>
  </xs:redefine>
</xs:schema>

最初の XSD で有効でなければならない XML の例 (ただし、2 番目の XSD では無効):

<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="example">
  <elA>MyString</elA>
</root>

両方のXSDで有効でなければならない XML の例

 <?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="example">
  <elA>MyString</elA>
  <newElement>MyNewString</newElement>
</root>

以前の XSD は「ユニーク パーティクル アトリビューション」に違反しており、これを修正してほしい。どちらの XSD も編集できますが、2 つ目を完成させる前に 1 つ目を配布できるようにしたいと考えています。

これを可能にするにはどうすればよいですか (JAXB によるチェック時に両方のスキーマが有効である必要があります)。

ありがとう

4

2 に答える 2

1

一部の人々は言うかもしれません:あなたが両方のXSDを編集できるなら、なぜ再定義を気にするのですか?

少なくともXSDの観点から、XSD再定義でそれを機能させる方法を紹介します。ただし、JAXBには制限があるため、そのままでは機能しません。追加の手順として自動XSDリファクタリングも使用する場合は、それを機能させることができ、その過程で、xsd:redefineを使用したときに表示される価値提案を維持できます。

したがって、その前に、これも合成を使用する別の方法ですが、;は使用しませんxsd:redefine。メンテナンスと検証の観点からは、ほぼ同じ価値と使用法が得られます。

最初のXSDをModel1と呼び、2番目のXSDをと呼びますModel2。まず、で使用する「構成による再利用」の側面を提供する1つのXSDから始めますxs:redefine

一般的なアイテム、xsd-allow-extension-compatibility-and-validation-common-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> 

Model1 "items"、xsd-allow-extension-compatibility-and-validation-model1-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:any namespace="##any" minOccurs="0" processContents="lax" /> 
    </xs:sequence> 
  </xs:complexType>  
</xs:schema> 

Model2 "items"、xsd-allow-extension-compatibility-and-validation-model2-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> 

Common ItemsとModel1、またはCommon ItemsとModel2をJAXBコンパイラに渡すと、希望どおりにクラスが作成されます。使いやすさ(テスト)と説明のために、さらに2つの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>

これは、Model1に対してxjcを実行したときに得られるものです。

@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を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」を意味し、矢印は「included」を指します。

QTAssistantXSDファイル図

更新:@Kevinのコメントに基づいて、再定義の新しい要素にmaxOccursがないことに気づきました。この場合、次のように1つの再定義を使用できます。

<?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のコメントに基づいて、2つは2つの再定義を回避し、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>

最終的な結果として、元のファイルはModel1のままで、新しいXSDを使用してModel1を検証できます。

于 2012-09-25T22:06:00.980 に答える
1

あなたが実際に欲しいのは制限です。ワイルドカードは、拡張を行った場合でもコンテンツ モデルの一部であるため、固有粒子属性違反が発生するのはそのためです。実際にやろうとしているのは、ワイルドカードをより制限的なもの、つまり特定の要素に置き換えることです。

于 2012-09-25T19:52:43.593 に答える