[英]Unmarshaller and schema in JAXB
我有應用程序,可以以各種格式保存文件(所有這些都是xml)。 所以我應該在確定格式文件已保存的情況下解決問題。 所以,我看到了2個解決方案
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "bla-bla.xsd");
所以我想我可以使用unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION)
來獲取它
但它扔了
javax.xml.bind.PropertyException:jaxb.noNamespaceSchemaLocation
和getSchema()
返回null那么, 我怎樣才能獲得模式位置?
setAdapter(Class<A> type, A adapter)
方法為不同的bean指定不同的適配器 什么方式更可取? 如果是第一個,那我怎樣才能獲得架構位置標簽?
upd 代碼示例假設我們有bean
@XmlRootElement
public class Foo{
String bar;
public String getBar() {return bar; }
public void setBar(String bar) {this.bar = bar;}
}
和生成模式的代碼,然后保存Foo的實例和加載。
public class Test {
final static String schemaLoc = "fooschema.xsd";
public static void write(File file, Foo foo, Schema schema) throws Throwable {
XMLEventWriter xsw = null;
try{
JAXBContext context = JAXBContext.newInstance(Foo.class);
XMLOutputFactory xof = XMLOutputFactory.newInstance();
OutputStream out = new FileOutputStream(file);
xsw = xof.createXMLEventWriter(out);
Marshaller m = context.createMarshaller();
m.setSchema(schema); //schema setted
System.out.println(">>>marchal : " + m.getSchema()); //check it
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, schemaLoc);
m.marshal(foo, xsw);
} finally{
xsw.close();
}
}
public static Foo load(File file) throws Throwable {
JAXBContext context = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
System.out.println("unmarshaller schema:" + unmarshaller.getSchema()); //I need get it here
// System.out.println("schema_prop:" + unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION));
InputStreamReader in = new InputStreamReader(new FileInputStream(file));
XMLEventReader xer = XMLInputFactory.newInstance()
.createXMLEventReader(in);
return Foo.class.cast(unmarshaller.unmarshal(xer));
}
private static File createSchema(String schemaLocation) throws Throwable{
final File target = new File(schemaLocation);
if(!target.exists()){
JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);
SchemaOutputResolver sor = new SchemaOutputResolver() {
public Result createOutput(String namespaceURI, String suggestedFileName)
throws IOException {
StreamResult result = new StreamResult(target);
result.setSystemId(target.toURI().toURL().toString());
return result;
}
};
jaxbContext.generateSchema(sor);
}
return target;
}
public static void main(String[] args) throws Throwable {
createSchema(schemaLoc);
File file = new File("temp.xml");
Foo foo = new Foo();
foo.setBar("test bar");
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(createSchema(schemaLoc));
write(file, foo, schema);
System.out.println("result " + load(file).getBar());
}
}
生成的模式
<xs:element name="foo" type="foo"/>
<xs:complexType name="foo">
<xs:sequence>
<xs:element name="bar" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
我們的臨時文件
<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fooschema.xsd">
<bar>test bar</bar></foo>
正如我們所見,有
的xsi:noNamespaceSchemaLocation = “fooschema.xsd”
我如何使用JAXB獲取此文本?
我將利用StAX解析器來獲取此信息(請參閱下面的示例)。 在輸入上創建XMLStreamReader。 使用nextTag()方法將XMLStreamReader推進到根元素。 然后獲取根元素的noNamespaceSchemaLocation屬性。 然后將XMLStreamReader傳遞給Unmarshaller上的unmarshal(XMLStreamReader)方法。
import java.io.FileInputStream;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Categories.class);
XMLInputFactory xif = XMLInputFactory.newInstance();
FileInputStream fis = new FileInputStream("input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(fis);
xsr.nextTag();
String noNamespaceSchemaLocation = xsr.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "noNamespaceSchemaLocation");
System.out.println(noNamespaceSchemaLocation);
Unmarshaller um = context.createUnmarshaller();
Categories response = (Categories) um.unmarshal(xsr);
}
}
您必須使用fileoutputstream參考文件為其提供架構的位置:
http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html
編輯:
很抱歉,在進一步閱讀之后,您實際上想要架構的位置,而不是XML文件,並且在線有很多示例。 大多數人喜歡這個:
http://robaustin.wikidot.com/how-to-improve-perforamance-of-jaxb
演示如何使用上下文類加載器傳遞模式位置。
編輯:
根據你的意見:
http://download.oracle.com/javase/6/docs/api/javax/xml/bind/Marshaller.html#getSchema%28%29
如果marshaller上沒有設置架構,則getSchema()將返回null。 這就是為什么你不能得到你想要的屬性,因為它(架構)不存在。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.