需要帮助解决JAXB解组问题



我遇到了典型的'unexpected element (uri:" local:"stickynote")' JAXB错误,尽管它只在我在解组器对象上设置事件处理程序时显示。当未设置事件处理程序时,代码可以正常运行,但所需的特定数据不会解组。

我已经研究这个问题好几天了,包括在互联网上搜索了很多次,但没有找到正确的解决方案。我觉得我错过了一些简单的东西,但到目前为止还没有。

指出:

  1. 我正在使用Java JDK 8和Apache NetBeans 15.
  2. 原始代码是用xjc命令从我们从多个供应商收到的模式中生成的。我不能修改模式,必须弄清楚如何"原样"使用它们。
  3. 我写了下面的代码来重复这个问题并简化发布的代码。为简洁起见,删除了Import语句。如果需要,请告诉我。
  4. 由于继承涉及到一个类,所以我添加了适当的@XmlSeeAlso注释。
  5. 这是我第一次真正接触JAXB。它似乎非常适合这个项目。我只需要想办法让它工作。

首先,示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<documents>
<document>
<notes>
<stickynote id="123">test note</stickynote>
</notes>
</document>
</documents>

创建JAXB上下文和Unmarshaller对象的代码:

JAXBContext context = JAXBContext.newInstance( Documents.class );
Unmarshaller u = context.createUnmarshaller();
u.setEventHandler(new DefaultValidationEventHandler());
JAXBElement< Documents > root =
u.unmarshal(
new StreamSource( new File( FILENAME )),
Documents.class );

处理每个元素的对应类:

<<p>文档类/strong>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "document" })
@XmlRootElement(name = "documents", namespace = "http://www.example.org/documents")
public class Documents {
protected Document document;
public Document getDocument() {
return document;
}
public void setDocument(Document document) {
this.document = document;
}
}

文档类

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "notes" })
@XmlRootElement(name = "document", namespace = "http://www.example.org/documents")
public class Document {
protected NotesType notes;
public NotesType getNotes() {
return notes;
}
public void setNotes(NotesType notes) {
this.notes = notes;
}
}
<<p>NotesType类/strong>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NotesType", propOrder = { "notes" })
public class NotesType {
protected List<NoteType> notes;

public List<NoteType> getNotes() {
if ( isNull( notes )) {
notes = new ArrayList<>();
}
return this.notes;
}
}
<<p>NoteType类/strong>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NoteType", propOrder = { "note" })
@XmlSeeAlso({ StickyNote.class })
public class NoteType {
@XmlAttribute(name = "id", required = true)
protected String id;
protected String note;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}

最后,便利贴类,它扩展了NoteType类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "subType" })
public class StickyNote extends NoteType {
protected String subType = "sticky";
public String getSubType() {
return subType;
}
public void setSubType(String subType) {
this.subType = subType;
}
}

例外是:

DefaultValidationEventHandler: [ERROR]: unexpected element (uri:"", local:"stickynote"). Expected elements are <{}notes> 
Location: line 5 of file:/C:/Test/documents.xml
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"stickynote"). Expected elements are <{}notes>
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
*and so on*

提前感谢任何和所有的建议和帮助!

约翰

我的问题原来是我如何使用xjc。我正在单独构建我们收到的每个模式,没有意识到由于供应商使用其他供应商的模式,模式中存在一些重叠。当一个供应商的模式在流程的早期构建,然后另一个供应商的模式在它之后使用较早的供应商的模式构建时,这会导致问题。

将所有模式作为一个组而不是单独构建,允许xjc"看到";它需要看到的所有东西和相应的代码都按预期工作。

最新更新