У меня есть приложение, которое может сохранять файлы в различных форматах (все они в формате 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()
возвращают ноль Итак, как я могу получить расположение схемы?
- Задание разных адаптеров для разных компонентов с использованием метода
setAdapter(Class<A> type, A adapter)
Какой способ предпочтительнее?Если сначала, то как я могу получить метку расположения схемы?
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?