【发布时间】:2014-03-30 01:51:58
【问题描述】:
我的 JAVA 程序使用类似于 GPX 1.1 的内部类层次结构,但并不完全相同。因为重写它以使 1:1 符合 GPX 是一项巨大的工作,所以我想一点一点地改变它,即将<metadata> 子树读入 MetadataType 类,就像使用来自 the XSD file 的 xjc 生成的一样。
用 DOM 解析剩余的 GPX 文件,直到出现 <metadata>:
private void parseMetadata(MetadataType metadata, Element element) throws JAXBException {
try {
System.out.println(element.getNodeName()); // output: metadata
JAXBContext context = JAXBContext.newInstance(MetadataType.class);
javax.xml.bind.Unmarshaller u = context.createUnmarshaller();
JAXBElement<MetadataType> meta = u.unmarshal(element, MetadataType.class);
metadata = meta.getValue();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(metadata.getName()); // NULL
System.out.println(metadata.getAuthor().getName()); // NULL
}
投掷
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"metadata"). Expected elements are <{http://www.topografix.com/GPX/1/1}gpx>
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
这个类看起来像这样:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "metadataType", propOrder = {
"name",
"desc",
"author",
"copyright",
"link",
"time",
"keywords",
"bounds",
"extensions"
})
@XmlRootElement(name = "metadata")
public class MetadataType {
protected String name = "";
protected String desc = "";
protected PersonType author;
protected CopyrightType copyright = new CopyrightType();
protected List<LinkType> link = new ArrayList<LinkType>();
@XmlSchemaType(name = "Date")
protected Date time;
protected String keywords = "";
protected BoundsType bounds = new BoundsType();
protected ExtensionsType extensions = new ExtensionsType();
[...]
}
是否可以从 XML 子树中解组;如果是,我做错了什么?
更新/1:
感谢 lexicore,我更进一步:element 肯定包含 metadata 节点,@XmlRootElement 已设置,现在使用 unmarshal(element, MetadataType.class) 解组。
解组工作,但对象的内容是空的。我想知道我是否在这里遇到了一些命名空间问题?
包com.topografix.gpx._1._1包含一个package-info.java,由xjc生成:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.topografix.com/GPX/1/1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.topografix.gpx._1._1;
这是其中一个测试文件:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
creator="GPSMAP 62s" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1
http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas /GpxExtensions/v3
http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1
http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1
http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2014-01-01T22:26:49Z</time>
</metadata>
[...]
UPDATE/2:命名空间/包名是正确的。如果命名空间设置为(即)“foobar”,则会引发以下异常:
javax.xml.bind.JAXBException: Provider com.sun.xml.internal.bind.v2.ContextFactory could not be instantiated:
javax.xml.bind.JAXBException: "foobar" doesnt contain ObjectFactory.class or jaxb.index
像之前一样初始化,没有抛出异常,说明命名空间正确,找到了ObjectFactory.class。
String contextPath = MetadataType.class.getPackage().getName();
JAXBContext context = JAXBContext.newInstance(contextPath);
所以,命名空间是正确的,但不知何故缺少指向 MetadataType 类的“链接”?
【问题讨论】: