Java JAXB—尝试在“中使用枚举”;xsd:any";标签
我会马上说,我毫不怀疑我的问题是自己造成的,但我已经尝试从我能想到的每个角度自己解决它,我仍然完全被难住了——任何帮助都将不胜感激 我试图完成的不是火箭科学——我得到了一个我称之为“提供”的模式,表示这是由第三方提供给我的(即,我无法更改/编辑它)。请注意,此模式包含一个xsd:any标记,用作放置用户定义数据的位置Java JAXB—尝试在“中使用枚举”;xsd:any";标签,java,jaxb,Java,Jaxb,我会马上说,我毫不怀疑我的问题是自己造成的,但我已经尝试从我能想到的每个角度自己解决它,我仍然完全被难住了——任何帮助都将不胜感激 我试图完成的不是火箭科学——我得到了一个我称之为“提供”的模式,表示这是由第三方提供给我的(即,我无法更改/编辑它)。请注意,此模式包含一个xsd:any标记,用作放置用户定义数据的位置 <xsd:schema xmlns="http://somecompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XML
<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>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "UserDefinedAreaType", propOrder = {
"any"
})
public class UserDefinedAreaType {
@XmlAnyElement(lax = true)
protected List<Object> any;
}
现在用一些简单的代码来测试这个
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>
显然要做的事情是将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(以及我计划填充到此用户区域的任何其他内容)设置为@XmlRootElement,但实际上我没有成功实现这一点!我要么缺少将MyEnum创建为@XmlRootElement的明显方法,要么我的方法存在根本性缺陷(即,我从错误的方向处理这个问题)
非常感谢任何人提出的任何想法。解决方案一-
架构更改:
<xsd:schema xmlns="http://mycompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mycompany.com/schema">
<xsd:element name="MyEnum" type="MyEnumType"/>
<xsd:simpleType name="MyEnumType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="active"/>
<xsd:enumeration value="inactive"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
也是一种有用的ObjectFactory方法,用于创建“MyEnums”(类型为“MyEnumType”):
@xmlementdecl(命名空间=”http://mycompany.com/schema“,name=“MyEnum”)
公共JAXBElement createMyEnum(MyEnumType值){
返回新的JAXBElement(_MyEnum_QNAME,MyEnumType.class,null,value);
}
完整路试代码:
private static final ObjectFactory of = new ObjectFactory();
private static final JAXBContext jc;
static {
try {
jc = JAXBContext.newInstance(Parent.class, MyEnumType.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);
JAXBElement<MyEnumType> goodEnum = of.createMyEnum(MyEnumType.fromValue("active"));
udat.getAny().add(goodEnum);
File file = new File("output.txt");
try {
Marshaller m = jc.createMarshaller();
m.marshal(parent, file);
} catch (JAXBException ex) {
ex.printStackTrace();
}
}
private static final ObjectFactory of=new ObjectFactory();
私有静态最终jaxbcontextjc;
静止的{
试一试{
jc=JAXBContext.newInstance(Parent.class,MyEnumType.class);
}捕获(JAXBEException-ex){
抛出新异常InInitializeRerror(ex);
}
}
公共静态void main(字符串[]args){
父项=新父项();
UserDefinedAreaType udat=新的UserDefinedAreaType();
父.setUserDefinedArea(udat);
JAXBElement goodEnum=of.createMyEnum(MyEnumType.fromValue(“活动”));
udat.getAny().add(goodEnum);
File File=新文件(“output.txt”);
试一试{
Marshaller m=jc.createMarshaller();
m、 封送员(父级、文件);
}捕获(JAXBEException-ex){
例如printStackTrace();
}
}
产生所需的输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Parent xmlns:ns2="http://somecompany.com/schema">
<UserDefinedArea>
<ns3:MyEnum xmlns:ns3="http://mycompany.com/schema">active</ns3:MyEnum>
</UserDefinedArea>
</ns2:Parent>
积极的
一个xsd:any
是任何元素的容器,但是您的模式没有声明任何元素,只有一个MyEnum
类型。如果您将附加模式作为顶级元素以匿名类型而不是顶级类型写入delcareMyEnum
<xsd:schema xmlns="http://mycompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mycompany.com/schema">
<xsd:element name="MyEnum">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="active"/>
<xsd:enumeration value="inactive"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:simpleType>
</xsd:schema>
然后您应该得到所需的
@XmlRootElement
注释。我之前确实尝试过这种方法-将simpleType包装到元素中,结果根本不创建类型。我唯一得到的是一个具有以下签名的ObjectFactory方法:public-JAXBElement-CreateMeyEnum(字符串值)
@XmlType(name = "MyEnumType", namespace = "http://mycompany.com/schema")
@XmlEnum
public enum MyEnumType {
@XmlEnumValue("active")
ACTIVE("active"),
@XmlEnumValue("inactive")
INACTIVE("inactive");
private final String value;
}
@XmlElementDecl(namespace = "http://mycompany.com/schema", name = "MyEnum")
public JAXBElement<MyEnumType> createMyEnum(MyEnumType value) {
return new JAXBElement<MyEnumType>(_MyEnum_QNAME, MyEnumType.class, null, value);
}
private static final ObjectFactory of = new ObjectFactory();
private static final JAXBContext jc;
static {
try {
jc = JAXBContext.newInstance(Parent.class, MyEnumType.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);
JAXBElement<MyEnumType> goodEnum = of.createMyEnum(MyEnumType.fromValue("active"));
udat.getAny().add(goodEnum);
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">
<UserDefinedArea>
<ns3:MyEnum xmlns:ns3="http://mycompany.com/schema">active</ns3:MyEnum>
</UserDefinedArea>
</ns2:Parent>
<xsd:schema xmlns="http://mycompany.com/schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://mycompany.com/schema">
<xsd:element name="MyEnum">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="active"/>
<xsd:enumeration value="inactive"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:simpleType>
</xsd:schema>