我在Netbeans 7.1.2中使用JaxB时遇到了问题。
我使用JaxB(New JaxB Binding)从模式自动生成了我的类。我正在使用Marshaller创建将序列化为XML字符串的对象,然后从XML String返回到新的对象实例。但是,我得到以下异常:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.somewhere.com/some/path", local:"MyQueryComplexTypeQuery"). Expected elements are (none)
编组/序列化到XML字符串工作正常。它是解组/反序列化导致问题的时候。
我使用以下代码构建对象并将其编组为XML字符串:
// build the object
ObjectFactory of = new ObjectFactory();
MyQueryComplexType oaaqc = of.createMyQueryComplexType();
oaaqc.setField1("edit");
oaaqc.setField2("net");
oaaqc.setField3("24");
JAXBElement<MyQueryComplexType> createMyQueryComplexType = of.createMyQueryComplexTypeQuery(oaaqc);
// serialise to xml
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
Marshaller m = context.createMarshaller();
m.marshal(createMyQueryComplexType, writer);
// output string to console
String theXML = writer.toString();
System.out.println(theXML);
这会在控制台中生成以下XML(格式化):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyQueryComplexTypeQuery xmlns="http://www.somewhere.com/some/path">
<Field1>edit</Field1>
<Field2>net</Field2>
<Field3>24</Field3>
</MyQueryComplexTypeQuery>
现在我使用以下代码将字符串反序列化/解组化为新实例MyQueryComplexType:
Unmarshaller u = context.createUnmarshaller();
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
在auto生成的package-info.java中,它包含以下内容:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.somewhere.com/some/path", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package MyProject.SomeNamespace.MyQuery;
我认为对象的简单过程 - &gt; string - &gt;对象会起作用。这是我第一次使用JaxB(所以要温和)。我看过其他帖子提到名称空间,一切看起来都不错。我已从模式自动生成类,构造了对象,编组为xml字符串。我认为简单地颠倒unmarshal的过程将是类似的。
实际的异常就行了:
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
我以为我正在做从字符串到对象的解组很简单。我不知道我做错了什么或遗漏了什么。我希望你们能发光或睁开我的眼睛。
我已经减少了代码,以简化我的应用中导致错误的内容。已更改命名空间以保护Web上的事物的身份。
有什么想法吗?
由于
Andez
答案 0 :(得分:17)
创建JAXBContext
对于从XML模式生成的JAXB模型,您可以在包名称上创建JAXBContext
而不是在特定类上创建:
JAXBContext context = JAXBContext.newInstance("your.package.name");
不是:
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
这将确保正确处理包含ObjectFactory
注释的@XmlElementDecl
类,这是您的用例中缺少的内容。
Unmarshal Operation
请注意,在编组操作期间,您需要将MyQueryComplexType
的实例包装在JAXBElement
中吗?这是因为MyQueryComplexType
未使用@XmlRootElement
进行注释,并且需要来自JAXBElement
的根元素信息。这意味着当你进行解组操作时,你也会得到一个JAXBElement
。
JAXBElement<MyQueryComplexTypeQuery> o = (JAXBElement<MyQueryComplexType>) u.unmarshal(new StringReader(theXML));
不
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
了解更多信息