我會馬上說一聲,我毫不懷疑納秒,我的問題在這裏是自我造成的,但我已經跑了從我能想到的每個角度自己修理它,我仍然完全難住 - 任何幫助將非常感謝!JAXB--嘗試在「xsd:any」標記中使用枚舉
我想要完成的不是火箭科學 - 我已經給出了一個模式,我打電話給「提供」來表示這是由第三方提供給我的(即我無法更改/編輯它)。請注意,此架構包含一個xsd:any標籤,用作放置用戶定義數據的地方。
<xsd:schema xmlns="http://somecompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://somecompany.com/schema">
<xsd:element name="Parent">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="UserDefinedArea" type="UserDefinedAreaType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="UserDefinedAreaType">
<xsd:sequence>
<xsd:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
使用XJC爲這個模式生成代碼很簡單。 XJC爲UserDefinedAreaType生成一個類,它給了我一個用戶定義數據的List。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UserDefinedAreaType", propOrder = {
"any"
})
public class UserDefinedAreaType {
@XmlAnyElement(lax = true)
protected List<Object> any;
}
一個我想塞進這個UserDefinedArea的事情是一個枚舉(增添一些額外的驗證/類型安全保證)。創建一個模式來表示這個也很簡單。
<xsd:schema xmlns="http://mycompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mycompany.com/schema">
<xsd:simpleType name="MyEnum">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="active"/>
<xsd:enumeration value="inactive"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
XJC很高興地爲這個模式創建一個類。
@XmlType(name = "MyEnum", namespace = "http://mycompany.com/schema")
@XmlEnum
public enum MyEnum {
@XmlEnumValue("active")
ACTIVE("active"),
@XmlEnumValue("inactive")
INACTIVE("inactive");
private final String value;
}
現在一些簡單的代碼來測試這個驅動器。
private static final ObjectFactory of = new ObjectFactory();
private static final JAXBContext jc;
static {
try {
jc = JAXBContext.newInstance(Parent.class);
} catch (JAXBException ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static void main(String[] args) {
Parent parent = new Parent();
UserDefinedAreaType udat = new UserDefinedAreaType();
parent.setUserDefinedArea(udat);
MyEnum myEnum = MyEnum.ACTIVE;
udat.getAny().add(myEnum);
File file = new File("output.txt");
try {
Marshaller m = jc.createMarshaller();
m.marshal(parent, file);
} catch (JAXBException ex) {
ex.printStackTrace();
}
}
這就是我希望得到的。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Parent xmlns:ns2="http://somecompany.com/schema" xlmns:ns3="http://mycompany.com/schema">
<UserDefinedArea>
<ns3:MyEnum>active</ns3:MyEnum>
</UserDefinedArea>
</ns2:Parent>
但這是我真正得到的。
javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: class com.mycompany.schema.MyEnum nor any of its super class is known to this context.
顯而易見的事情將是MyEnum.class添加到JAXBContext中(即「JC = JAXBContext.newInstance(Parent.class,MyEnum.class);」),但所有的網我的是:
javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: unable to marshal type "com.mycompany.schema.MyEnum" as an element because it is missing an @XmlRootElement annotation]
下一個明顯的事情是讓MyEnum(和其他任何我打算塞進這個UserArea)的@XmlRootElement,但我有零次成功實際上使這種情況發生!我要麼缺少創建MyEnum作爲@XmlRootElement的明顯方法,要麼我的方法存在根本性缺陷(即,我正從錯誤的方向接近這個問題)。
非常感謝任何人可能有的想法。
我其實早些時候嘗試過這種方法 - 在一個元素中包裝simpleType最終不會創建一個類型。我唯一得到的是一個帶有這個簽名的ObjectFactory方法:public JAXBElement createMyEnum(String value) –
Nick