XML 序列化

XML序列化是将XML数据从 Db2 表格中的内部表示形式转换为应用程序中的文本XML格式的过程。

您可以调用XMLSERIALIZE函数,请求 Db2 数据库服务器在将XML数据发送到客户端应用程序之前执行XML序列化。 这个过程被称为显式序列化。 或者,您可以省略XMLSERIALIZE调用,直接从XML列中获取数据并将其放入应用程序变量中。 Db2 数据库服务器在检索过程中对XML数据进行序列化。 这个过程被称为隐式序列化。

借助隐式序列化,在客户机支持 XML 数据类型的情况下,将数据发送至客户机时数据具有 XML 类型。 对于 Db2 、 ODBC 和嵌入式SQL应用程序, Db2 数据库服务器会在数据中添加XML声明,并附带适当的编码规范。 对于Java™应用程序, Db2 数据库服务器不会添加XML声明,除非您使用已弃用的 DB2Xml.getDB2Xmlxxx 方法来检索数据。

在大多数情况下,隐式序列化是首选方法。 向客户端发送XML数据,使 Db2 客户端能够正确处理XML数据。 明确的序列化需要客户进行额外的处理。

您可以以二进制XML格式(Extensible Dynamic Binary XML Db2 Client/Server Binary XML Format )而不是文本XML数据的形式检索XML数据,以避免序列化。 仅 JDBC、SQLJ或 ODBC 应用程序或UNLOAD实用程序支持以二进制XML格式检索数据。

在显式调用 XMLSERIALIZE 之后,数据在数据库服务器中具有非 XML 数据类型,并且以该数据类型发送至客户机。

XMLSERIALIZE 允许您指定:
  • 序列化时数据转换为的 SQL 数据类型

    数据类型为CLOB、BLOB、DBCLOB。

  • 输出数据是否应包含以下明确的XML声明(EXCLUDING XMLDECLARATION或INCLUDING XMLDECLARATION):
    <?xml version="1.0" encoding="UTF-8"?>
来自 XMLSERIALIZE 的输出是 Unicode UTF-8 编码的数据。

请确保您了解在执行 XMLSERIALIZE 时请求明确编码规范的含义。 如果将文本XML数据转换为非二进制数据类型,数据将转换为应用程序编码,但编码规范不会修改。 因此,数据的编码可能与编码规范不一致。 这种情况会导致应用程序无法解析依赖于编码名称的XML数据。

一般来说,隐式序列化更可取。 然而,在以下情况下,最好执行显式的 XMLSERIALIZE:
  • 当 XML 文档非常大时

    因为没有XML定位器,如果XML文档非常大,您可以使用XMLSERIALIZE将数据转换为LOB类型,以便使用LOB定位器。

  • 当客户机不支持 XML 数据时

    如果客户端是不支持XML数据类型的早期版本,并且您使用隐式XML序列化,则 Db2 数据库服务器会将数据转换为BLOB数据类型。 如果您希望检索的数据为其他数据类型,可以动态执行SQL语句,调用XMLSERIALIZE指定CLOB或DBCLOB输出。

  • 当您想将XML数据传递给存储过程或用户定义的函数时

    Db2 for z/OS® 存储过程和用户定义的函数不支持XML数据类型的参数。 因此,如果您想将数据从XML列传递给常规,则需要调用XMLSERIALIZE将数据转换为BLOB、CLOB或DBCLOB类型。

最好将 XML 数据转换为 BLOB 数据类型,因为检索二进制数据会导致较少的编码问题。

示例:样本表 Customer 中的 XML 列 Info 包含一个文档,该文档包含等价于下列数据的分层:
<customerinfo xml:space="default" xmlns="http://posample.org" Cid='1000'>
  <name>Kathy Smith</name>
  <addr country='Canada'>
  <street>5 Rosewood</street>
  <city>Toronto</city>
  <prov-state>Ontario</prov-state>
  <pcode-zip>M6W 1E6</pcode-zip>
  </addr>
  <phone type='work'>416-555-1358</phone>
</customerinfo>
调用 XMLSERIALIZE 以在将数据检索到主变量中之前序列化该数据并将它转换为 BLOB 类型。
SELECT XMLSERIALIZE(Info as BLOB(1M)) from Customer
  WHERE CID='1000'
示例 :在C程序中,将客户ID为1000的客户信息文档作为BLOB主机变量以XML格式读取。 这样做会导致隐式XML序列化。 检索到的数据使用 UTF-8 编码方案,并且包含 XML 声明。
EXEC SQL BEGIN DECLARE SECTION;
 SQL TYPE IS XML AS BLOB (1M) xmlCustInfo;
EXEC SQL END DECLARE SECTION;
…
EXEC SQL SELECT INFO INTO :xmlCustInfo
  FROM Customer
  WHERE Cid=1000;
示例 :此 JDBC 程序通过以二进制数据格式检索数据来避免XML序列化。 该程序将 DataSource 属性 xmlFormat 设置为二进制XML格式,以指示应以此格式检索数据。 然后,程序将客户编号为1000的客户信息文件检索到SQLXML对象中。 接下来,程序将数据从SQLXML对象中提取到 DOMSource 对象中,以便以非文本形式显示提取的数据。 此技术需要使用 JDBC 4.0 或更高版本。
import java.sql.*;                        // JDBC base
import com.ibm.db2.jcc.*;                 // IBM Data Server Driver for JDBC
                                          // and SQLJ implementation of JDBC
…
com.ibm.db2.jcc.DB2SimpleDataSource db2ds =  
  new com.ibm.db2.jcc.DB2SimpleDataSource();
                                          // Create the DataSource object
db2ds.setDriverType(4);                   // Set the driver type
db2ds.setDatabaseName("san_jose");        // Set the location
db2ds.setUser("db2adm");                  // Set the user
db2ds.setPassword("db2adm");              // Set the password
db2ds.setServerName("mvs1.sj.ibm.com");  
                                          // Set the server name
db2ds.setPortNumber(5021);                // Set the port number
db2ds.setXMLFormat(
  com.ibm.db2.jcc.DB2BaseDataSource.XML_FORMAT_BINARY);
                                          // Set XML format to binary
…
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT INFO FROM Customer WHERE Cid='1000'");
SQLXML sqlxml = rs.getSQLXML(1);
DOMSource domSource = sqlxml.getSource(DOMSource.class); 
                                         // Get a DOMSource object from 
                                         // the SQLXML object, to avoid
                                         // XML serialization
Document document = (Document) domSource.getNode();