简体   繁体   English

需要帮助解决 JAXB 解组问题

[英]Need help resolving a JAXB unmarshall issue

I am having the typical 'unexpected element (uri:"", local:"stickynote")' JAXB error, although it only shows when I set the event handler on the unmarshaller object. When the event handler is not set code runs fine, but the specific data needed is not unmarshalled.我遇到了典型的“意外元素(uri:”,本地:“stickynote”)'JAXB 错误,尽管它仅在我在 unmarshaller object 上设置事件处理程序时显示。当事件处理程序未设置时,代码运行正常,但所需的特定数据并未解组。

I have worked on the problem for a couple of days, including many Inte.net searches, and am not hitting on the right solution.我已经处理这个问题几天了,包括许多 Inte.net 搜索,但没有找到正确的解决方案。 I feel like I am missing something simple, but so far it is eluding me.我觉得我遗漏了一些简单的东西,但到目前为止它一直在躲避我。

Notes:笔记:

  1. I am using Java JDK 8 with Apache NetBeans 15.我正在使用 Java JDK 8 和 Apache NetBeans 15。
  2. The original code was generated with the xjc command from schemas we receive from multiple vendors.原始代码是使用 xjc 命令从我们从多个供应商处收到的模式生成的。 I cannot modify the schemas and have to figure out how to use them "as is".我无法修改模式,必须弄清楚如何“按原样”使用它们。
  3. I wrote the code below to duplicate the issue and simplify the posted code.我写了下面的代码来复制这个问题并简化发布的代码。 Import statements have been removed for brevity.为简洁起见,已删除导入语句。 If they are needed please let me know.如果需要,请告诉我。
  4. Since inheritance is involved in one of the classes, I added the appropriate @XmlSeeAlso annotation.由于其中一个类涉及 inheritance,因此我添加了适当的@XmlSeeAlso注释。 That did not help.那没有帮助。
  5. This is my first real foray into JAXB. It seems to be perfect for this project.这是我第一次真正涉足 JAXB。它似乎非常适合这个项目。 I just have to figure out how to get it to work.我只需要弄清楚如何让它工作。

First, example XML:首先以XML为例:

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

Code to create the JAXB context and create the Unmarshaller object:创建 JAXB 上下文和创建 Unmarshaller object 的代码:

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 );

The corresponding classes to handle each element:处理每个元素的相应类:

Documents class证件class

@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;
    }
}

Document class文件 class

@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;
    }
}

NotesType class备注类型 class

@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;
    }
}

NoteType class NoteType class

@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;
    }
}

And finally, the StickyNote class, which extends the NoteType class:最后是StickyNote class,它扩展了NoteType class:

@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;
    }
}

The exception is:例外是:

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*

Thanks in advance for any and all suggestions and help!在此先感谢您的任何和所有建议和帮助!

john约翰

My issue turned out to be how I was using xjc.我的问题原来是我如何使用 xjc。 I was building each schema we received individually, not realizing there was some overlap in the schemas due to the vendors using other vendors schemas.我正在构建我们单独收到的每个模式,没有意识到由于供应商使用其他供应商模式,模式中存在一些重叠。 This caused issues when one vendor's schema was built early in the process and then another vendor's schema was built after it that used the earlier vendor's schema.当一个供应商的架构在流程的早期构建,然后另一个供应商的架构在它之后使用早期供应商的架构构建时,这会导致问题。

Building all the schemas as a group, instead of individually, allowed xjc to "see" everything it needed to see and the corresponding code worked as expected.将所有模式构建为一个组,而不是单独构建,允许 xjc “看到”它需要看到的一切,并且相应的代码按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM