java xml bind
Marshaller 和 Unmashaller
Mashaller
Unmashaller
Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 对象的过程,可选择在解组时验证 XML 数据。 它为许多不同的输入类型提供了重载解组方法。
从文件解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
Object o = u.unmarshal( new File( "nosferatu.xml" ) );
从输入流解组:
InputStream is = new FileInputStream( "nosferatu.xml" );
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
Object o = u.unmarshal( is );
从URL解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
URL url = new URL( "http://beaker.east/nosferatu.xml" );
Object o = u.unmarshal( url );
使用 javax.xml.transform.stream.StreamSource 从 StringBuffer 解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
StringBuffer xmlStr = new StringBuffer( "<?xml version="1.0"?>..." );
Object o = u.unmarshal( new StreamSource( new StringReader( xmlStr.toString() ) ) );
从org.w3c.dom.Node解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File( "nosferatu.xml"));
Object o = u.unmarshal( doc );
使用客户端指定的 SAX2.0 解析器从 javax.xml.transform.sax.SAXSource 解组:
// configure a validating SAX2.0 parser (Xerces2)
static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
static final String JAXP_SCHEMA_LOCATION = "http://java.sun.com/xml/jaxp/properties/schemaSource";
static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
System.setProperty( "javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl" );
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
SAXParser saxParser = spf.newSAXParser();
try {
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
saxParser.setProperty(JAXP_SCHEMA_LOCATION, "http://....");
} catch (SAXNotRecognizedException x) {
// exception handling omitted
}
XMLReader xmlReader = saxParser.getXMLReader();
SAXSource source = new SAXSource( xmlReader, new InputSource( "http://..." ) );
// Setup JAXB to unmarshal
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
ValidationEventCollector vec = new ValidationEventCollector();
u.setEventHandler( vec );
// turn off the JAXB provider's default validation mechanism to
// avoid duplicate validation
u.setValidating( false )
// unmarshal
Object o = u.unmarshal( source );
// check for events
if( vec.hasEvents() ) {
// iterate over events
}
从StAX XMLStreamReader解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
javax.xml.stream.XMLStreamReader xmlStreamReader =
javax.xml.stream.XMLInputFactory().newInstance().createXMLStreamReader( ... );
Object o = u.unmarshal( xmlStreamReader );
从StAX XMLEventReader解组:
JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller u = jc.createUnmarshaller();
javax.xml.stream.XMLEventReader xmlEventReader =
javax.xml.stream.XMLInputFactory().newInstance().createXMLEventReader( ... );
Object o = u.unmarshal( xmlEventReader );
解组 XML 数据
解组可以反序列化表示整个 XML 文档或 XML 文档子树的 XML 数据。
通常,使用全局声明的Unmarshal 根元素描述的解组方法就足够了。
这些解组方法利用 JAXBContext 将全局 XML 元素声明和类型定义映射到 JAXB 映射类来启动 XML 数据根元素的解组。
当 JAXBContext 的映射不足以解组 XML 数据的根元素时,应用程序可以通过使用声明类型的解组方法来帮助解组过程。
这些方法对于解组 XML 数据很有用,其中根元素对应于模式中的本地元素声明。解组方法永远不会返回 null。
如果解组过程无法将 XML 内容的根解组到 JAXB 映射对象,则会报告致命错误,通过抛出 JAXBException 终止处理。
解组全局声明的根元素
没有declaredType的解组方法使用JAXBContext 解组 XML 数据的根元素。
JAXBContext实例是用于创建此解组器的实例。
JAXBContext实例维护全局声明的 XML 元素和类型定义名称到JAXB 映射类。
unmarshal 方法检查 JAXBContext 是否有映射从根元素的 XML 名称和/或 xsi:type 到 JAXB 映射类。
如果有,它会调整XML 数据使用适当的 JAXB 映射类。
请注意,当根元素名称未知且根元素有一个xsi:type,XML 数据被解组使用该 JAXB 映射类作为JAXBElement 的值。
当JAXBContext 对象没有根元素名称的映射时也不是它的 xsi:type,如果它存在,然后解组操作将通过抛出UnmarshalException 立即中止解组异常。可以通过使用解组来解决此异常情况下一小节中描述的声明类型方法。
按声明类型解组
带有declaredType的解组方法使应用程序能够反序列化 XML 数据的根元素,即使在根元素的 XML 名称的 JAXBContext 中没有映射时也是如此。
解组器使用指定为declaredType的应用程序提供的映射来解组根元素。
请注意,即使根元素的元素名称由 JAXBContext 映射,但在使用这些解组方法时,declaredType会覆盖用于反序列化根元素的映射。
此外,当 XML 数据的根元素具有 xsi:type 属性并且该属性的值引用由 JAXBContext 映射到 JAXB 映射类的类型定义时,根元素的 xsi:type 属性优先于解组方法中声明的类型参数 .
这些方法总是返回一个 JAXBElement 实例。
下表显示了如何设置返回的 JAXBElement 实例的属性。
按声明的类型解组返回的 JAXBElement |
---|
JAXBElement Property | Value |
---|---|
name | xml 元素名称 |
value | declaredType实例 |
declaredType | 解组方法declaredType参数 |
scope | null (actual scope is unknown) |
下面是一个通过声明类型方法解组例子
根据 org.w3c.dom.Node 中的声明类型解组:
模式片段例如
<xs:schema>
<xs:complexType name="FooType">...<\xs:complexType>
<!-- 全局元素声明“PurchaseOrder”-->
<xs:element name="PurchaseOrder">
<xs:complexType>
<xs:sequence>
<!-- 局部元素声明“foo”-->
<xs:element name="foo" type="FooType"/>
...
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
JAXBContext jc = JAXBContext.newInstance("com.acme.foo");
Unmarshaller u = jc.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
文档 doc = db.parse(new File("nosferatu.xml"));
元素 fooSubtree = ...; // 遍历 DOM 直到到达 xml 元素 foo,受 a 约束
// 模式中的本地元素声明。
// FooType 是本地元素声明 foo 类型的 JAXB 映射。
JAXBElement<FooType> foo = u.unmarshal( fooSubtree, FooType.class);