我是JAXB的新手,我正试图解组某个XML XML是:
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0">
<Schema xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:sap="http://www.sap.com/Protocols/SAPData" xmlns="http://schemas.microsoft.com/ado/2009/11/edm" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" Namespace="smallApp">
</Schema>
</edmx:DataServices>
我已经构建了一个类似于以下类的模式:
Edmx.java
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "edmx:Edmx")
public class Edmx {
@XmlElement(name = "edmx:DataServices")
private DataService dataService;
public DataService getDataService() {
return dataService;
}
}
DataService.java
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "edmx:DataServices")
public class DataService {
@XmlElement(name = "Schema")
private Schema schema;
public Schema getSchema() {
return schema;
}
}
和Schema.java
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Schema")
public class Schema {
}
然后,我构建了一个示例方法,用Edmx.class解组上述XML:
public class Parser {
public static void main(String[] args) {
File fXmlFile = new File("somePathToXML");
try {
InputStream inputStream = new FileInputStream(fXmlFile);
Edmx edmx = load(Edmx.class, inputStream);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* loads an object from an xml file
* @param <T>
* @param type
* @param file
* @return
*/
public static <T> T load(Class<? extends T> type, InputStream stream) {
try {
if(stream.available() == 0) {
return null;
}
JAXBContext context = JAXBContext.newInstance(type);
Unmarshaller um = context.createUnmarshaller();
@SuppressWarnings("unchecked")
T obj = (T) um.unmarshal(stream);
return obj;
} catch (JAXBException jaxbe) {
System.out.println("failed to read from InputStream");
jaxbe.printStackTrace();
return null;
} catch (IOException ioe) {
System.out.println("InputStream is empty");
return null;
}
}
}
我一直遇到的错误是:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.microsoft.com/ado/2007/06/edmx", local:"Edmx"). Expected elements are <{}Schema>,<{}edmx:DataServices>,<{}edmx:Edmx>
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)
的
这很奇怪,因为我没有任何不期望的元素:(
有人有想法吗?
答案 0 :(得分:0)
您可以执行以下操作:
<强>包信息强>
您可以使用包级别@XmlSchema
注释来指定模型的命名空间限定。下面我已经指定,除非另有说明,否则所有元素都将由http://schemas.microsoft.com/ado/2007/06/edmx
命名空间限定。我还指定该命名空间的首选前缀是edmx,http://schemas.microsoft.com/ado/2007/06/edmx
应该是默认命名空间。
@XmlSchema(
namespace="http://schemas.microsoft.com/ado/2007/06/edmx",
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
@XmlNs(prefix="edmx", namespaceURI="http://schemas.microsoft.com/ado/2007/06/edmx"),
@XmlNs(prefix="", namespaceURI="http://schemas.microsoft.com/ado/2009/11/edm")
}
)
@XmlAccessorType(XmlAccessType.FIELD)
package forum14875956;
import javax.xml.bind.annotation.*;
<强> EDMX 强>
现在不需要在Edmx
类上指定名称空间信息。
package forum14875956;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Edmx")
public class Edmx {
@XmlElement(name = "DataServices")
private DataService dataService;
public DataService getDataService() {
return dataService;
}
}
<强>的DataService 强>
在DataService
类中,我们将在schema
属性的映射上指定命名空间。
package forum14875956;
import javax.xml.bind.annotation.*;
public class DataService {
@XmlElement(name = "Schema", namespace = "http://schemas.microsoft.com/ado/2009/11/edm")
private Schema schema;
public Schema getSchema() {
return schema;
}
}
<强>模式强>
您可以使用Schema
注释覆盖@XmlType
类上的属性的名称空间限定。
package forum14875956;
import javax.xml.bind.annotation.XmlType;
@XmlType(namespace="http://schemas.microsoft.com/ado/2009/11/edm")
public class Schema {
}
<强>演示强>
package forum14875956;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Edmx.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum14875956/input.xml");
Edmx edmx = (Edmx) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(edmx, System.out);
}
}
<强> input.xml中/输出强>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<edmx:DataServices>
<Schema/>
</edmx:DataServices>
</edmx:Edmx>
了解更多信息