我正在尝试使用JAXB解组以下XML:
<artist xmlns="http://www.spotify.com/ns/music/1">
<name>Basement Jaxx</name>
<albums>
<album href="spotify:album:3xOulZzGRe4Ycwm59iCdKg">
<name>Back 2 the Wild</name>
<artist href="spotify:artist:4YrKBkKSVeqDamzBPWVnSJ">
<name>Basement Jaxx</name>
</artist>
<released>2013</released>
<id type="upc">5055489272702</id>
<album>
</albums>
</artist>
当我在相册中的艺术家上使用@XmlTransient
来跳过它时,无论如何都会对其进行解析。
如何才能使JAXB正确处理标记为@XmlTransient
的字段?
编辑1 - 文件
测试xml:
<artist>
<name>Adema</name>
<albums>
<album href="spotify:album:07tjJowJIddz8c74x5WOvj">
<name>Topple the Giants</name>
<artist href="spotify:artist:3n4ersmDo55xV4fPSCKpXb">
<name>Adema</name>
</artist>
<released>2013</released>
<id type="upc">886443922082</id>
<availability>
<territories>AD AT AU BE CA CH DE DK EE ES FI FR GB HK IE IS IT LI LT LU LV MC MX MY NL NO NZ PL PT SE SG US</territories>
</availability>
</album>
<album href="spotify:album:06QaJLqG068uXHQbAcPZKU">
<name>Kill The Headlights</name>
<artist href="spotify:artist:3n4ersmDo55xV4fPSCKpXb">
<name>Adema</name>
</artist>
<released>2007</released>
<id type="upc">4030816195283</id>
<availability>
<territories>AD AT BE CH DE DK EE ES FI FR GB IE IS IT LI LT LU LV MC NL NO PL PT SE</territories>
</availability>
</album>
</albums>
</artist>
XTest.java:
package dao.spotify;
import dao.spotify.lookup.entities.LookupArtist;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.helpers.DefaultValidationEventHandler;
public class XTest {
public XTest() {
load();
}
public void load() {
try {
File file = new File("c:/tmp/test5.xml");
JAXBContext jc = JAXBContext.newInstance(LookupArtist.class);
Unmarshaller um = jc.createUnmarshaller();
um.setEventHandler(new DefaultValidationEventHandler());
LookupArtist spotifyArtistWrapper = (LookupArtist) um.unmarshal(file);
System.err.println("Done");
} catch (JAXBException ex) {
ex.printStackTrace();
}
}
public static void main(String... args) {
XTest test = new XTest();
}
}
LookupArtist.java:
package dao.spotify.lookup.entities;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "artist")
@XmlAccessorType(XmlAccessType.FIELD)
public class LookupArtist {
@XmlElement
private String name;
@XmlElementWrapper(name = "albums")
@XmlElement(name = "album")
private List<LookupInnerAlbum> albums = new ArrayList();
}
LookupInnerAlbum.java:
package dao.spotify.lookup.entities;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name = "album")
@XmlAccessorType(XmlAccessType.FIELD)
public class LookupInnerAlbum {
@XmlAttribute
private String href;
private String name;
private int released;
private String id;
private LookupInnerAvailability availability;
@XmlTransient
private LookupInnerArtist artist;
}
LookupInnerAvailability.java:
package dao.spotify.lookup.entities;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "availability")
@XmlAccessorType(XmlAccessType.FIELD)
public class LookupInnerAvailability {
@XmlElement
private String territories;
}
LookupInnerArtist.java:
package dao.spotify.lookup.entities;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(name = "artist")
@XmlAccessorType(XmlAccessType.FIELD)
public class LookupInnerArtist {
@XmlElement
private String name;
@XmlAttribute
private String href;
}
运行时,我得到:
DefaultValidationEventHandler: [ERROR]: unexpected element (uri:"", local:"artist"). Expected elements are <{}id>,<{}released>,<{}name>,<{}availability>
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"artist"). Expected elements are <{}id>,<{}released>,<{}name>,<{}availability>
Location: line 6 of file:/c:/tmp/test5.xml
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:662)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:258)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:253)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:120)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:105)
at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:262)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:498)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:480)
at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:150)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2717)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:489)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:258)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:229)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:136)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:141)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:150)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:168)
at dao.spotify.XTest.load(XTest.java:30)
at dao.spotify.XTest.<init>(XTest.java:21)
at dao.spotify.XTest.main(XTest.java:38)
答案 0 :(得分:1)
当我运行你的例子时,我得到同样的东西。错误消息是正确的unexpected element (uri:"", local:"artist")
元素存在于XML中,但您尚未映射到它。您已映射到的<{}id>,<{}released>,<{}name>,<{}availability>
元素<{}artist>
未显示在那里,因为您已使用@XmlTransient
将其排除在外。
DefaultValidationEventHandler: [ERROR]: unexpected element (uri:"", local:"artist"). Expected elements are <{}id>,<{}released>,<{}name>,<{}availability>
Location: line 6 of file:/Users/bdoughan/GIT/EclipseLink-Trunk3/Scratch/src/dao/spotify/test5.xml
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"artist"). Expected elements are <{}id>,<{}released>,<{}name>,<{}availability>
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
关于DefaultValidationEventHandler
的说明。此类表示JAXB 1.0的默认验证事件规则,它们与JAXB 2.0不同。以下内容来自Javadoc(参见:http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/helpers/DefaultValidationEventHandler.html)
JAXB 1.0仅默认验证事件处理程序。这是默认值 从正在管理的JAXBContext创建的所有对象的处理程序 由JAXB 1.0绑定编译器生成的模式派生代码。
此处理程序导致unmarshal和validate操作失败 第一个错误或致命错误。
此处理程序不是JAXB映射类的默认处理程序 遵循JAXB 2.0或更高版本。默认验证事件 处理已经改变,并在Unmarshaller和Marshaller中指定。
如果您未将此指定为ValidationEventHandler
,那么您的文档将被正确解组。
我害怕我不明白;我以为我画了艺术家 指定:私人LookupInnerArtist艺术家;?换的时候 DefaultValidationEventHandler到ValidationEventCollector(正确吗?) 即使我指定了艺术家,一切都很好 @XmlTransient。
由于您已指定@XmlAccessorType(XmlAccessType.FIELD)
,因此除了使用@XmlTransient
注释的字段外,所有字段都将被视为已映射。
我在调试时仍然可以看到艺术家,尽管它有一个空值。
即使artist
注明了@XmlTransient
,它仍然可以在您的课程中使用。由于它现在被认为是未映射的,因此不会被解组操作填充。
了解更多信息