我是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”。每个“actor-def”都属于一个使用ID和IDREF实现的“actor-system-def”。
为了使用JAXB,我使用Eclipse的JAXB Classes for Schema创建工具自动创建了所有必需的类。它根据XSD文件自动创建以下类:
Policy.java
ActorDef.java
ActorSystemDef.java
ActorSystemType.java
除了ActorDef.java文件和其中使用XRE文件中的IDREF定义的actorSystem变量的类型外,一切看起来都很好。基本上,ActorDef.java文件具有以下内容:
@XmlElement(name = "actor-system", required = true)
protected ActorSystemType actorSystem;
public ActorSystemType getActorSystem() {
return actorSystem;
}
问题在于,由于ActorDef.getActorSystem()返回的类型是ActorSystemType类型,因此它是对错误对象的引用。我想要的是对相关ActorSystemDef的引用,以便我可以在其上调用getName()方法来获取ActorSystemDef的名称(如下所示)
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;
}
这解决了问题并且代码工作正常但我想学习如何纠正我的XSD文件,以便JAXB类创建工具自动纠正上述问题。我认为我在我的XSD定义中犯了一个错误。我经常修改我的XSD文件,并且不能每次都手动进行所有这些更改。
答案 0 :(得分:1)
我尝试了你的架构,得到了ActorDef
类,和你一样:
@XmlElement(name = "actor-system", required = true)
protected ActorSystemType actorSystem;
public ActorSystemType getActorSystem() { return actorSystem; }
public void setActorSystem(ActorSystemType value) { this.actorSystem = value; }
但后来我删除了你这部分架构(因为它似乎你没有使用它 - 为什么它在那里?):
<xsd:complexType name="actor-system-type">
<xsd:attribute name="name" type="xsd:IDREF" use="required" />
</xsd:complexType>
然后更改了actor-system
元素的type
:
<xsd:element name="actor-system" type="tns:actor-system-type"/>
要:
<xsd:element name="actor-system" type="tns:actor-system-def"/>
因此,结束模式变为:
<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-def"/>
</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>
然后使用这个,我生成了类,并为ActorDef
得到了这个:
@XmlElement(name = "actor-system", required = true)
protected ActorSystemDef actorSystem;
public ActorSystemDef getActorSystem() { return actorSystem; }
public void setActorSystem(ActorSystemDef value) { this.actorSystem = value; }
在我看来,这首先是你期待的,对吗?
此外,应该是,ActorSystemType.java
不再生成。
答案 1 :(得分: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,则不允许引用它。相反,你必须在actor-def。
中创建一个新的actor系统我能够通过更改您的代码解决问题,如下所示:
<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() );