有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

}

也实现了getter和setter

现在我得到了以下异常:

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) 个答案

  1. # 1 楼答案

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

    @XmlRootElement(name = "ROOT")
    public class DocumentList {
    
        @XmlElement(name="DOCUMENT")
        private List documents;
    
        @XmlElement(name="TEXT")
        private List texts;
    
        @XmlElement(name="ITEMS")
        private List items;
    
    }
    
  2. # 2 楼答案

    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中的元素列表映射

    我希望你能理解

  3. # 3 楼答案

    如果您想将这个用例表示为一个列表,有两种不同的方法来支持它(见下文)。也可以将其表示为单独的列表

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

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

    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-多个元素对应于同一类

    如果List中条目的Class不足以唯一地将其映射到元素,则需要利用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注释

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