gpt4 book ai didi

java - JAXB 列表中的不同元素

转载 作者:数据小太阳 更新时间:2023-10-29 03:02:38 25 4
gpt4 key购买 nike

我有一些具有以下结构的 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> ?我做错了什么?

最佳答案

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

选项 #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 注释,我们还需要在使用 @XmlRegistry 注释的类上提供 @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);
}

}

关于java - JAXB 列表中的不同元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23334989/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com