我有一个代码,它使用带有SAX的JAXB来将xml源解组为java对象。后来我读了this文档并且知道如果我不提供SAX解析器,JAXB提供程序将选择默认解析器。默认解析器意味着什么?如果我不提供SAX 2.0解析器,它会使用DOM或任何其他技术解析文档吗?或者它会使用小于2.0版本的SAX解析器。
我们正在使用javax.xml.bind jaxb-api。我怎么知道它使用哪个SAX解析器。如果我必须使用带有JAXB的SAX2.0编译解析器,那么不同的解析器可用。什么是这种混乱?我完全搞砸了。 Atleast我想阅读一个很好的文档,它解释了解析技术,使用哪个解析器以及不同类型的解析器和不同类型的JAXB提供程序等。
直到现在我才知道JAXB是一个规范。 Oracle分发的标准java提供了规范的默认实现。此外还有其他实现,如Metro,Eclipselink MOXy,apache camel的JAXB实现。刚才我知道如果我理解正确,解析技术中会使用不同的解析器版本。
答案 0 :(得分:0)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
后来我读了这个文件,并且知道如果我不提供 SAX解析器,JAXB提供程序将选择默认解析器。是什么 默认解析器意味着什么?
当你要求JAXB (JSR-222)实现解组像InputStream
之类的东西时,JAXB实现可以自由地解析XML(即SAX,StAX或某些专有解析器)。
如果您想强制您的JAXB实现使用特定的SAX解析器,那么您可以执行以下操作之一:
选项#1 - UnmarshallerHandler
import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.XMLReader;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(unmarshallerHandler);
xr.parse("input.xml");
Foo foo = (Foo) unmarshallerHandler.getResult();
}
}
选项#2 - SAXSource
您可以在SAXSource
上创建XMLReader
的实例,并让JAXB解组。 JAXB将使用传入的XMLReader
。
import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
InputSource xml = new InputSource("input.xml");
SAXSource saxSource = new SAXSource(xr, xml);
Foo foo = (Foo) unmarshaller.unmarshal(saxSource);
}
}
直到现在我才知道JAXB是一个规范。标准的java 由Oracle分发给出了一个默认的实现 规格。此外还有其他实施,如Metro, Eclipselink MOXy,apache camel的JAXB实现。刚才我来了 要知道在解析中使用了不同的解析器版本 技术,如果我理解得当。
最终知道JAXB实现使用哪个底层解析器并不重要(它甚至可以在不同版本之间进行更改)。需要JAXB实现来传递TCK,并将继续以一致的方式工作。如果您希望它使用特定的SAX解析器,请使用上述方法之一。如果你想让它使用StAX,则将XMLStreamReader
的实例传递给unmarshal,如果你想让它使用DOM,则将Document
的实例传递给unmarshal。