1

私は XSD 設計と JAXB の両方に不慣れです。以下のように XSD を作成できました。

<xsd:element name="policy" >
<xsd:complexType>
    <xsd:sequence>
        <xsd:element name="actor-def" type="tns:actor-def"/>                        
        <xsd:element name="actor-system-def" type="tns:actor-system-def"/>           
        </xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:complexType name="actor-def">
    <xsd:sequence>
        <xsd:element name="actor-system" type="tns:actor-system-type"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:ID" use="required" />
</xsd:complexType>
<xsd:complexType name="actor-system-type">
    <xsd:attribute name="name" type="xsd:IDREF" use="required" />
</xsd:complexType>

<xsd:complexType name="actor-system-def">
    <xsd:attribute name="name" type="xsd:ID" use="required" />
    <xsd:attribute name="url" type="xsd:anyURI" use="required" />
</xsd:complexType>

基本的に、いくつかの「actor-def」と「actor-system-def」を定義できる「policy」のルート要素があります。各「actor-def」は、ID と IDREF を使用して達成される 1 つの「actor-system-def」に属します。

これで JAXB を使用するために、Eclipse の JAXB Classes for Schema 作成ツールを使用して、必要なすべてのクラスを自動的に作成しました。XSD ファイルに基づいて、次のクラスが自動的に作成されます。

ポリシー.java

ActorDef.java

ActorSystemDef.java

ActorSystemType.java

ActorDef.java ファイルと、XSD ファイルで IDREF を使用して定義されたその中のactorSystem 変数のタイプを除いて、すべて問題ないように見えます。基本的に、ActorDef.java ファイルには次のものがあります。

@XmlElement(name = "actor-system", required = true)
protected ActorSystemType actorSystem;
public ActorSystemType getActorSystem() {
    return actorSystem;
}

これの問題は、ActorDef.getActorSystem() から返される型が ActorSystemType 型であるため、間違ったオブジェクトへの参照になることです。私が欲しいのは、関連する ActorSystemDef への参照です。これにより、その ActorSystemDef の名前を取得するために getName() メソッドを呼び出すことができます (以下に示すように)。

JAXBContext myJAXBContext = JAXBContext.newInstance("spec_jaxb");
Unmarshaller myUnmarshaller = myJAXBContext.createUnmarshaller();
Policy myPolicy = (Policy) myUnmarshaller.unmarshal(new  File("src/main/java/spec/private_policy.xml"));

List<ActorDef> actorList = myPolicy.getActorDef();
for (ActorDef actor : actorList) {
    System.out.println(actor.getActorSystem().getName());
}

JAXB ツールによって自動的に作成されたクラスを手動で変更することで、コードを機能させることができました。以下のように、ActorDef.java の actorSystem 変数の型を ActorSystemDef に変更しました。

protected ActorSystemDef actorSystem;
public ActorSystemDef getActorSystem() {
    return actorSystem;
}

これで問題は解決し、コードは正常に動作しますが、上記の問題が JAXB クラス作成ツールによって自動的に修正されるように、XSD ファイルを修正する方法を知りたいです。これを引き起こしている XSD 定義を間違えていると思います。私は XSD ファイルを頻繁に変更しますが、毎回手動ですべての変更を行うことはできません。

4

2 に答える 2

0

@acdcjunior: 最後のコメントに続いて、提供されたソリューションでは次のようなコードは許可されません。

  <tns:actor-def>
    <tns:name>actor1</tns:name>
    <tns:description>actor 1 desc</tns:description>
    <tns:type>local</tns:type>
    <tns:actor-reference>www.actor.com</tns:actor-reference>
    <tns:actor-system>
      <tns:name>actor-system-1</tns:name>
    </tns:actor-system>
  </tns:actor-def>
  <tns:actor-system-def>
    <tns:name>actor-system-1</tns:name>
    <tns:description>actor-system-1 desc</tns:description>
    <tns:url>http://actorsystem1.org</tns:url>
    <tns:port>80</tns:port>
  </tns:actor-system-def>

実際、actor-system-1 が既に定義されている場合、それを参照することはできません。代わりに、アクター定義内から新しいアクター システムを作成する必要があります。

以下のようにコードを変更することで問題を解決できました。

<xsd:element name="policy">
<xsd:complexType>
    <xsd:sequence>
        <xsd:element name="actor-def" type="tns:actor-def"/>
        <xsd:element name="actor-system-def" type="tns:actor-system-def"/>
    </xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:complexType name="actor-def">
    <xsd:sequence>
        <xsd:element name="actor-system" type="xsd:IDREF"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:ID" use="required" />
</xsd:complexType>

<xsd:complexType name="actor-system-def">
    <xsd:attribute name="name" type="xsd:ID" use="required" />
    <xsd:attribute name="url" type="xsd:anyURI" use="required" />
</xsd:complexType>

JAXB クラスが作成されると、ActorDef.java と ActorSystemDef.java しかなく、ActorDef.getActorSystem() のコードは次のようになります。

@XmlElement(name = "actor-system", required = true)
@XmlIDREF
@XmlSchemaType(name = "IDREF")
protected Object actorSystem;    

public Object getActorSystem() {
        return actorSystem;
    }

これは、キャストを使用して ActorSystemDef オブジェクトに簡単に変換できます。

system.out.println(   ((ActorSystemDef) actor.getActorSystem()).getName()  );
于 2013-04-18T00:05:56.920 に答える