JAXB列表中的不同元素

时间:2014-04-28 07:28:47

标签: java xml jaxb

我有一些XML文件具有以下结构:

<?xml version="1.0" encoding="iso-8859-1"?>
<ROOT xmlns="http://www.XXX.com/YYY"
    xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
    <DOCUMENT>
        <title>Doc 1</title>
    </DOCUMENT>
    <DOCUMENT>
        <title>Doc 2</title>
    </DOCUMENT>
    <TEXT>
        <content>Text 1</content>
    </TEXT>
    <TEXT>
        <content>Text 2</content>
    </TEXT>
    <ITEM>
        <id>1</id>
    </ITEM>
    <ITEM>
        <id>2</id>
    </ITEM>
</ROOT>

我想使用JAXB解析文件,因此我必须为所有元素创建模型。但是ROOT元素的模型是什么? XML中是否允许将不同的数据类型放在一个列表中?

我打电话给我的模型DocumentList,但我的列表的通用类型是什么?我可以使用一个列表来执行此操作,还是必须创建不同的列表?

@XmlRootElement(name = "ROOT")
public class DocumentList {

    private List elements;

}

提前致谢!

更新

我的模型类看起来像这样:

@XmlRootElement(name = "ROOT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement(name = "DOCUMENT")
    private List<Document> documents;

    @XmlElement(name = "TEXT")
    private List<Text> texts;

    @XmlElement(name = "ITEM")
    private List<Item> items;

}

@XmlRootElement(name = "DOCUMENT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Document {

    @XmlElement(name = "title")
    private String title;

}

@XmlRootElement(name = "TEXT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Text {

    @XmlElement(name = "content")
    private String content;

}

@XmlRootElement(name = "ITEM")
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

    @XmlElement(name = "id")
    private String id;

}

也实施了吸气剂和制定者。

现在我收到以下异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.XXX.com/YYY", local:"ROOT"). Expected elements are <{}DOCUMENT>,<{}TEXT>,<{}ITEM>,<{}ROOT>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    at com.siemens.xmlmerger.Test.main(Test.java:53)

为什么期望<{}ROOT>?我做错了什么?

3 个答案:

答案 0 :(得分:2)

我使用三个不同的列表(每种类型一个)。

@XmlRootElement(name = "ROOT")
public class DocumentList {

    @XmlElement(name="DOCUMENT")
    private List documents;

    @XmlElement(name="TEXT")
    private List texts;

    @XmlElement(name="ITEMS")
    private List items;

}

答案 1 :(得分:2)

如果要将此用例表示为单个列表,可以使用几种不同的方法来支持此用例(请参阅下文)。您也可以将其表示为单独的列表。

选项#1 - 每个元素对应一个唯一类

如果列表中的每个元素名称对应不同的类,那么您可以通过利用List并执行以下操作来使用一个@XmlElements

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "ROOT")
@XmlAccessorType(XmlAccessType.FIELD)
public class DocumentList {

    @XmlElements({
       @XmlElement(name="DOCUMENT", type=Document.class),
       @XmlElement(name="TEXT", type=Text.class),
       @XmlElement(name="ITEM", type=Item.class)
    })
    private List elements;

}

选项#2-多个元素对应同一类

如果Class中条目的List不足以将其唯一映射到元素,那么您将需要利用JAXBElement来维护元素信息。请注意我们如何删除@XmlElements注释并将其替换为@XmlElementRefs

import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "ROOT")
@XmlAccessorType(XmlAccessType.FIELD)
public class DocumentList {

    @XmlElementRefs({
       @XmlElementRef(name="DOCUMENT", type=JAXBElement.class),
       @XmlElementRef(name="TEXT", type=JAXBElement.class),
       @XmlElementRef(name="ITEM", type=JAXBElement.class)
    })
    private List elements;

}

除了@XmlElementRefs / @XmlElementRef注释外,我们还需要在使用@XmlElementDecl注释的类上提供@XmlRegistry注释。

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {

    @XmlElementDecl(name="DOCUMENT")
    public JAXBElement<String> createDocument(String value) {
        return new JAXBElement<String>(new QName("DOCUMENT"), String.class, value);
    }

    @XmlElementDecl(name="TEXT")
    public JAXBElement<String> createText(String value) {
        return new JAXBElement<String>(new QName("TEXT"), String.class, value);
    }

    @XmlElementDecl(name="ITEM")
    public JAXBElement<String> createItem(String value) {
        return new JAXBElement<String>(new QName("ITEM"), String.class, value);
    }

}

答案 2 :(得分:0)

xml中的元素将映射到绑定类的属性

所以

@XmlRootElement(name = "ROOT")
public class DocumentList {

    @XmlElement(name="DOCUMENT")
    private List documents;

    @XmlElement(name="TEXT")
    private List texts;

    @XmlElement(name="ITEMS")
    private List items;

在上面的类中,属性与xml中的元素列表一起映射。

我希望你明白