Unmarshalling (计算机科学)

unmarshalling，或译作“解集”，是计算机科学中把已经变换为适合于存储或传输的对象的表示，变换为可执行的对象表示的过程。一个unmarshalling接口把序列化对象变换为可执行形式。Unmarshalling是marshalling的逆过程。

用途 
通常，进程间通信时，需要发送XML对象。接收到数据的进程需要把它转化回可执行对象以便使用。因此unmarshalling通常用于Java远程方法调用（RMI）与远程过程调用（RPC）机制实现的接收端以把传送的对象转化为可执行形式。

JAXB 
JAXB或Java语言架构的是最常用的架构，实现marshal与unmarshal Java对象。JAXB提供了在Java的基本数据类型与XML schema标准支持的数据类型之间的相互转化。

XmlSerializer 
XmlSerializer是C#实现marshal与unmarshal C#对象的框架。由于包含XmlSerializer类，C#本地支持marshalling。

XML与可执行程序的表示
Unmarshalling的一个例子是把一个对象的XML表示转化为该对象在任何编程语言的默认可执行的表示。例如，下述类：public class Student
{
    private char name[50];
    private int ID;
    public String getName()
    {
        return this.name;
    }
    public int getID()
    {
        return this.ID;
    }
    void setName(String name)
    {
        this.name = name;
    }
    void setID(int ID)
    {
        this.ID = ID;
    }
}
  Student对象的XML表示: 
<!-- Code Snippet: 1 -->

<?xml version = “1.0” encoding = “UTF-8”?>
    <student id = “11235813”>
        <name>Jayaraman</name>
    </student>
    <student id = “21345589”>
        <name>Shyam</name>
    </student>
 Student对象的可执行表示: 
//Code Snippet: 2

Student s1 = new Student();
s1.setID(11235813);
s1.setName(“Jayaraman”);
Student s2 = new Student();
s2.setID(21345589);
s2.setName(“Shyam”);

从对象的XML表示（在代码片段1中）到Java默认的可执行表示（在代码片段2中）的转换过程称为unmarshalling。

JAXB的Unmarshaller 
对象的XML表示到Java默认的可执行表示的转换过程，由内建的Unmarshaller类负责。同时也验证了收到的XML的有效性。Unmarshaller类中的unmarshal方法对不同类型的XML输入是重载的。一些比较重要的unmarshal方法的实现有：
 从XML文件Unmarshalling：
JAXBContext jcon = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller umar = jcon.createUnmarshaller();
Object obj = umar.unmarshal( new File( "input.xml" ) );
 从一个XML文件作为输入流中Unmarshalling：
InputStream istr = new FileInputStream( "input.xml" );
JAXBContext jcon = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller umar = jcon.createUnmarshaller();
Object obj = umar.unmarshal( istr );
 从一个来自于URL的XML文件中Unmarshalling：
JAXBContext jcon = JAXBContext.newInstance( "com.acme.foo" );
Unmarshaller umar = jcon.createUnmarshaller();
URL url = new URL( "http://merrilllynch.employee/input.xml" );
Object obj = umar.unmarshal( url );

XML数据的Unmarshalling
Unmarshal方法可以反序列化（deserialize）整个XML文档或者它的一部分。

Unmarshal一个全局XML根元素 
当XML根元素被全局声明，这些方法利用JAXBContext把XML根元素映射为JAXB的映射类以初始化unmarshalling。JAXBContext对象总是维护全局声明的XML元素到JAXB映射类名字之间的映射。如果XML元素名字或它的@xsi:type属性匹配JAXB映射类，unmarshal方法把XML数据变换为合适的JAXB映射类。但是如果XML元素名字不匹配，unmarshal过程将abort并抛出UnmarshalException。可用declaredType参数unmarshal以避免这种异常。

Unmarshal一个局部XML根元素  
如果映射不是充分的且根元素被局部声明，unmarshal方法是用应用程序提供的declaredType参数来unmarshalling过程。根据优先次序，即使根名字映射到一个合适的JAXB类，declaredType能覆盖这个映射。但是如果XML数据的@xsi:type属性映射到合适的JAXB类，将优先于declaredType参数。有declaredType参数的Unmarshal方法总是返回JAXBElement<declaredType>实例。该JAXBElement实例属性总是如下设置：

与反序列化的对比 
对象的序列化是把它表示为字节流；反序列化是转化为最初对象的副本。 

对象被marshalled是从最初的内存状态与所包含的codebase记录下来；unmarshaller接口自动转化被marshalled的数据为Java在JAXB中可执行的代码。可被反序列化的对象就可被unmarshalled；反之不然。

参见 
 Marshalling (计算机科学)
 Java Architecture for XML Binding

参考文献
 
 
遠端程序呼叫