gpt4 book ai didi

java - JAXB 中的解码器和模式

转载 作者:搜寻专家 更新时间:2023-11-01 02:17:19 25 4
gpt4 key购买 nike

我的应用程序可以保存各种格式的文件(所有格式都是 xml)。所以我应该通过确定保存的格式文件来解决问题。所以,我看到了 2 个解决方案

  • 不同的格式有不同的模式,所以我可以根据它们来确定。我以从 here 获得的方式设置模式

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) 为不同的 beans 指定不同的适配器方法

哪种方式比较好?如果是第一个,那么如何获取架构位置标签?

更新代码示例假设我们有 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);
}
}

关于java - JAXB 中的解码器和模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4478666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com