2017-09-14 4 views
0

ich eine XML mit der folgenden Struktur:JAXB Unmarshalling Probleme, wenn Wrapperelement und Wurzelelement sind die gleichen

<?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> 

Ich habe folgende Mapping-Klassen:

CatalogFeed.java

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

KatalogTitle.java

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

Wenn ich Parsing mit dieser Setup versuchen (die Unmarshalling-Klasse ist generisch und es funktioniert gut für mehrere andere Dateien und die Model-Klasse ist ziemlich einfach und hat nur Komfort-Methoden wie OverRidden toString, die eine JSON-Version des Objekts druckt. Nichts XML verwandt), erhalte ich die folgende Ausnahme:

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) 

Interessanterweise, wenn ich alle Attribute catalog_titles entfernen und lassen Sie es so wie der Parser funktioniert gut.

Ich habe keine Kontrolle über die XML-Struktur und möchte, wenn möglich, die Vorverarbeitung und Manipulation der ursprünglichen Feed-Datei vermeiden. Gibt es eine bessere Möglichkeit, meine Klassen zu kommentieren, um die Ausnahme zu vermeiden?

P.S: Ich generiere meine Klassen nicht automatisch und sie sind alle handschriftlich basierend auf den XML-Feldern.

Antwort

1

Sie müssen die Namensräume für Ihre Elemente-Modelle definieren:

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

Dank. Keine Ausnahmen, aber alle gemappten Felder werden nicht geladen. Sollte ich den Namespace übergreifend verwenden, einschließlich der Felder in der CatalogTitle-Klasse? – user1452030

+0

Legen Sie es in allen '@ XmlElement'-Attributen fest. – teppic

+0

Wenn es viele von ihnen gibt, können Sie den Standard-Namespace mit einer '@ XmlSchema'-Annotation in der Paketinfo festlegen (siehe http://blog.bdoughan.com/2010/08/jaxb-namespaces.html). – teppic

Verwandte Themen