当包装器元素和根元素相同时,JAXB解组问题

时间:2017-09-14 07:24:46

标签: java xml jaxb

我有一个具有以下结构的XML:

<?xml version="1.0" encoding="UTF-8"?>
<catalog_titles xmlns="http://www.company.com/catalog3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.company.com/catalog3 catalog3.xsd" version="1.0" created="2017-04-26T07:31:12.443Z" language="en" country="xx">
  <catalog_title id="80153288" type="product1">
    ... Catalog specific fields ...
  </catalog_title>
  <catalog_title id="2" type="product2">
  </catalog_title">
</catalog_titles>

我有以下映射类:

CatalogFeed.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="catalog_titles")
public class CatalogFeed extends Model {
    @XmlElement(name="catalog_title")
    List<CatalogTitle> catalogTitles;
}

CatalogTitle.java

@XmlAccessorType(XmlAccessType.FIELD)
public class CatalogTitle extends Model {
    @XmlAttribute(name="id")
    private int id;
    ... Other fields with similar mappings
}

当我尝试使用此设置进行解析时(解组类是通用的,它适用于其他几个文件,而且Model类非常基本,并且只有方便的方法,比如覆盖了toString的方法,可以打印对象的JSON版本)。没有XML相关),我得到以下异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.company.com/catalog3", local:"catalog_titles"). Expected elements are <{}catalog_titles>
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189)
at com.mycompany.ingestion.importer.parser.GenericParser.parse(GenericParser.java:19)
at com.mycompany.ingestion.importer.Importer.lambda$0(Importer.java:64)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at com.mycompany.ingestion.importer.Importer.loadFeedData(Importer.java:62)
at com.mycompany.ingestion.importer.Importer.run(Importer.java:43)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
at com.mycompany.ingestion.importer.ImporterApplication.main(ImporterApplication.java:10)

有趣的是,如果我删除了catalog_titles的所有属性并将其保留为,则解析器工作正常。

我无法控制XML结构,如果可能的话,我想避免预处理和操作原始Feed文件。是否有更好的方法来注释我的类以避免异常?

P.S:我不会自动生成我的类,它们都是基于XML字段的手工输入。

1 个答案:

答案 0 :(得分:1)

您需要为元素模型定义名称空间:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace = "http://www.company.com/catalog3", name = "catalog_titles")
public static class CatalogFeed {
    @XmlElement(namespace = "http://www.company.com/catalog3", name = "catalog_title")
    List<CatalogTitle> catalogTitles;
}