内容


使用 DB2 9 pureXML 管理 ODF 和 Microsoft Office 2007 文档™

结合使用 IBM DB2 9 和 PHP 的 PDO 和 XQuery 存储和再利用数据

Comments

简介

桌面文档有什么新变化?如果您一直在关注 Microsoft Windows® 社区,那么您会发现变化实在太大了。 Microsoft 为 MS Office 2007 产品引入了一种新格式,这种格式可以在内部利用 XML。 之前,可以在 MS Office 应用程序之间交换数据;但是,MS Office 2007 和 Windows Vista® 允许企业踏入数据孤岛,而在以前,这些数据难以使用和再利用(re-purpose,即将用于某一目的的数据用于另一个目的)。虽然 Microsoft 正在推动这个概念,但 OpenOffice 应用程序已经实现了 ODF,并从市场早已认可的 XML 优点中受益。

让我们来看一个典型的桌面应用程序问题。假设有这样一家公司,它的市场部门正在计划召开一个会议。 他们要求预期的演讲者在一份 MS Word 模板文档中提交提议,然后,文档内容被用于以下任务:

  • 审核提议
  • 向成功提交提议的可能的演讲者发送电子邮件
  • 将相关信息发布到会议网站上
  • 通过会议或公司的一个新提要(ATOM/RSS)发布内容

按照传统做法,市场人员从 Word 文档中剪切文本,并将信息粘贴到不同的系统中,这种做法很费时。 如果保留文档原有格式,而为特定任务提取相关信息,则可以节省不少时间和精力。通过 XQuery 就可以做到这一点,而且只需很少的代码。

在本文中,我们将简要地回顾 MS Office 应用程序使用的一些旧的文档数据交换方法。然后,我们将查看新的格式,并讨论如何交换和再利用这种新格式。我们将使用 Zend Core for IBM、PHP、PDO 和 XQuery 等跨平台技术 —— 这些工具都可以与 DB2 结合使用。

这种技巧可以成为内容管理和文档管理解决方案中很有价值的一部分。希望您阅读本文之后发现,通过使用 IBM DB2 pureXML™ 特性,使用和再利用 ODF 和 MS Office 2007 文档不再是难事。这并不需要很多的代码,所以这个解决方案很容易实现。然后,您可能希望索引这些 Office 2007 文档,以进一步利用 pureXML 混合存储特性。

桌面应用程序和 XML 概述

本文主要关注 OpenOffice 默认格式 ODF 和 MS Office 2007 格式。您应该清楚,这里谈到的概念并不局限于这些格式和供应商。实际上,您会发现,很多供应商都提供了 ODF,包括 Google Applications、KOffice 和 StarOffice。值得注意的是,Microsoft 有一个用于使用和导入 ODF 格式的转换器 “插件”,并且有一个兼容包,可以用旧版本的 Office 打开和保存 MS Office 2007 文件格式。而且,Lotus Notes 和 Corel 也有 ODF 格式方面的计划。

Wikipedia 提供了有关 ODF 格式及其在桌面应用程序中的使用的讨论,并提供了关于 ODF 的支持者的信息。

所需资源

虽然可以下载 Apache 2.0、PHP Version 5.21 或更高版本、DB2 Express-C 和 DB2 extensions for PHP,但是下载和安装 Zend Core for IBM 是更好的选择。安装程序会彻底配置适合 PHP 和 DB2 的环境。安装程序应该包括 DB2 Express-C 9.1.2 的下载链接。可能需要调整配置,以添加 ZIP 支持,这一点我们在后面会讨论到。

老式的文档数据交换

Windows 操作系统上的数据应用程序编程接口(API)从 Data Access Objects (DAO) 开始。它们经历了从 DAO(不是 Dead On Arrival)到 Remote Data Objects (RDO),再到 Open Database Connectivity (ODBC) 的过程。向 ODBC 的转变意义重大,被认为数据访问的一个里程碑。它实现了一种通用的方式,使开发人员对一种 API 编码,而不必考虑数据库的类型。通过使用 ODBC,可以借助 Mail Merge 之类的程序将关系数据导入到 MS Office 应用程序中。

Object Linking and Embedding Data Base (OLE/DB) 支持不同数据源的数据交换,然而它的引入只是使市场感到困惑。对于 MS Office 生产率工具,这意味着文档之间可以相互嵌套。实际上,当将一个电子表格粘贴到一个演示文稿中时,就是如此。然而,OLE/DB 是只用于 Windows 的解决方案。使用这些技术分解文档并不容易,并且这个过程难以自动化。

OpenOffice 和新的 MS Office 2007 格式概述

这些格式实际上是一个包含资源和用于 XML 文档的文件夹的 ZIP 文件。Word 文档的实际文本内容以 XML 文件的形式存储。在我们的示例文档中,它在归档文件中的 “word/document.xml” 中。这种文件格式使开发人员可以捕捉这些文档中的实际数据。

虽然 OpenOffice 使用这种格式已经有一段时间了,但 MS Office 2007 只是最近才引入新的文档格式。Microsoft 声称,这种格式易于访问和易于共享。很多年来,MS Office 文档一直都是专用的。令人振奋的是,Microsoft 的 Office 小组正在打开这扇门。请看下面提供的用于 ODF 的 ZIP 文件内容(可在 下载 小节中找到):

图 1. WinZip 中 opendoc.odt 的内容
WinZip 文件演示了 Word 2007 文档包含有 XML 文档
WinZip 文件演示了 Word 2007 文档包含有 XML 文档

请看下面的 Microsoft 格式,注意其中有些不同,但概念和格式是类似的:

图 1.1 WinZip 中 submit.docx 的内容
WinZip 文件演示了 Word 2007 文档包含有 XML 文档
WinZip 文件演示了 Word 2007 文档包含有 XML 文档

设置数据库

当然,您需要创建一个表。您将把新的 Word 格式中的 XML 存储在 XML 列中,而不是一个 Character Large Object (CLOB) 中。为此,需要创建一个支持 XML 或 UTF-8 的数据库。

清单 1. 创建一个支持 XML 的数据库
CREATE DATABASE ODF AUTOMATIC STORAGE YES USING CODESET UTF-8 TERRITORY US

现在,需要连接到数据库,并用下面的定义创建一个表。下面的代码假设您有一个具有 CREATETAB 权限的用户名 “db2admin”。如果不具备这种用户设置,可以修改这些脚本,使具有适当的数据库用户。

清单 2. 创建用于包含 ODF 和 MS Office 2007 文档的支持 XML 的表
CREATE TABLE DB2ADMIN.DOCUMENT (
         ID INT NOT NULL PRIMARY KEY,
         OWNER VARCHAR(128),
         DOC XML
       )

设置 PHP 和 Zend Core for IBM

代码将使用 PHP 的 ZIP 实用程序和 PDO。PDO 已经针对 Zend Core for IBM 设置完毕,但是需要将 “zip” 添加到配置中:

  1. 打开 Zend Core Administration Console
  2. 切换到 Configuration 选项卡和 Extensions 子选项卡。
  3. 向下滚动到 ZIP 扩展。
  4. 单击 switch 图标将其打开。
  5. 单击 Save Settings
  6. 重新启动 Apache2。
    1. 如果它不在运行,即在系统托盘中显示为红色羽毛,那么启动 C:\Program Files\Zend\Apache2\bin\ApacheMonitor.exe
    2. 单击它,从菜单中重新启动 Apache2 HTTP Server。

如果这样不行,那么试着编辑文件,确保 “C:\Program Files\Zend\Core for IBM\etc” 文件夹下的 php.ini 文件中包含下面几行。将下面用粗体表示的一行添加到 php.ini 中:

清单 3. 对 php.ini 的修改
extension=php_zip.dll
extension=php_pdo.dll
extension=php_pdo_ibm.dll
extension_dir="c:\program files\Zend\Core for IBM\lib\phpext"

使用 ODF 和 MS Office 2007 文档

现在,可以开始使用 opendoc.odt 了,它是下载小节中提供的一个 ODF 文件。虽然 图 2 显示了该文档的 MS Word 外观,但这个 ODF 文件看起来类似于 清单 4。该文档使用像 “Heading 1” 和 “Heading 2” 这样的样式作为格式。然后,我们将查询 Heading 2 样式,因为 OpenOffice 格式中使用了它。注意,在生产代码中,还需要包括适当的错误处理代码。

我还在下载小节中包括了一个 submit.docx 文档,该文档使用 MS Office 2007 格式。图 2 显示这个文档在 Word 中的样子。和 ODF 一样,该文档利用 “Heading 1” 和 “Heading 2” 之类的 Word 样式作为格式。然后,我们将查询 Heading 2 样式。

图 2. OpenOffice 或 MS Word 中显示的示例文档
 Word 2007 中显示的 Word 2007 文档
Word 2007 中显示的 Word 2007 文档

下面的 PHP 代码使用了这个文档,它对 ZIP 清单中的项进行遍历,并提取具有相关数据的 XML 文档。清单 4 提供了该代码。将该代码保存为 “odfconsume.php”,以便后面引用。

清单 4. 使用 OpenOffice (ODF) 格式 (odfconsume.php) 的 PHP 代码
<?php
$user = "db2admin";
$password = "secret";
$zip = zip_open("c:\opendoc.odt");


$db = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=ODF;" .
  "HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;", $user, $password);
echo $user." Connected\n";

if ($zip) {

    while ($zip_entry = zip_read($zip)) {

        if (zip_entry_open($zip, $zip_entry, "r")
        && zip_entry_name($zip_entry) == 'content.xml' ) {

            $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));

            $insstr ="INSERT INTO DB2ADMIN.DOCUMENT (ID,OWNER,DOC)
            VALUES (2,'Linux Office',:buf)";

            $stmt = $db->prepare( $insstr );
            $stmt->bindParam( ':buf' , $buf , PDO::PARAM_LOB , strlen($buf) );
            $stmt->execute();

            echo "\nResult: ".$db->errorCode()."\n";

            zip_entry_close($zip_entry);

        }
        echo "\n";
    }
    zip_close($zip);

}
?>

使用下面的命令行运行该代码:

 php odfconsume.php

这会将一个 XML 文档插入到数据库中,并打印出一个错误码。这里错误码很可能是 0。

清单 4.1 是使用 MS Word 的代码。将该代码保存为 “msconsume.php”,以便后面引用。

清单 4.1 使用 MS Office 2007 格式 (msconsume.php) 的 PHP 代码
<?php
  $user = "db2admin";
  $password = "secret";	
  $zip = zip_open("c:\submit.docx");
  $db = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=ODF;" .
    "HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;", $user, $password);
  echo $user." Connected\n";


  if ($zip) {

     while ($zip_entry = zip_read($zip)) {

        if (zip_entry_open($zip, $zip_entry, "r") & 
                 zip_entry_name($zip_entry) == 'word/document.xml' ) {

            $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
	    $insstr ="INSERT INTO DB2ADMIN.DOCUMENT VALUES (1,'BILLY ONAIRE',:buf)";
	    $stmt = $db->prepare( $insstr );
	    $stmt->bindParam( ':buf' , $buf , PDO::PARAM_LOB , strlen($buf) );
  	    $stmt->execute();
	    echo "Result: ".$db->errorCode();
            zip_entry_close($zip_entry);
        }
        echo "\n";
    }
    zip_close($zip);

  }

?>

和前面一样,用下面的命令行运行该代码:

 php msconsume.php

这会将一个 XML 文档插入到数据库中,并打印出一个错误码。同样,这里错误码很可能是 0。

再利用 ODF 和 Word 2007 内容

现在,在数据库中有了 OpenOffice 和 Word 2007 文档的内容,您需要再利用该文档,将它用于网站。这就是我们例子中市场部门必须要做的事情。清单 5 显示了用于 ODF 的代码,可以将该代码保存为 “odfrepurpose.php”,以便后面引用。从 输出(一个 HTML 片段)中,很容易看到如何将这个文档重新格式化为一个新闻提要,或者将它并入到一个 Ajax 应用程序中!

清单 5. 将 ODF 格式(opendoc.odt)再利用到一个简单的 HTML 片段中
<?php
$user = "db2admin";
$password = "secret";	

$db = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=ODF;" .
  "HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;", $user, $password);
echo $user." Connected\n";


$xqry = 
<<<TXT
values( 
  XMLSERIALIZE( XMLQUERY(' 
     declare boundary-space strip;
     declare namespace text0="urn:oasis:names:tc:opendocument:xmlns:text:1.0";
     declare namespace office0="urn:oasis:names:tc:opendocument:xmlns:office:1.0";

    for \$t0 in db2-fn:xmlcolumn("DB2ADMIN.DOCUMENT.DOC")
    /office0:document-content/office0:body
       let \$p0 := \$body0/office0:text/text0:p
       let \$h0 := \$body0/office0:text/text0:h
       where fn:exists(\$p0) or \$h0:h/@text:style-name ="Heading_20_2"
       return  
         if ( fn:exists( \$style ) ) then 
            if (\$h0:h/@text:style-name ="Heading_20_2" )  then <h1>{\$txt}</h1>
            else  () 
         else <p>{\$txt}</p>') 
  as VARCHAR(2000)))
TXT;

$result=$db->query( $xqry );
$arr = $result->fetch();
echo $arr[1];

?>

清单 5.1 显示了再利用 Word 2007 的代码,可以将该代码保存为 “msrepurpose.php”,以便后面引用。从 输出(一个 HTML 片段)中,很容易看到如何将这个文档重新格式化为一个新闻提要,或者将它并入到一个 Ajax 应用程序中!

清单 5.1 将 Word 2007 格式(submit.docx)再利用到一个简单的 HTML 片段中
                <?php
                    $user = "db2admin";
                    $password = "secret";
                    $db = new PDO("ibm:DRIVER={IBM DB2 ODBC DRIVER};DATABASE=ODF;" .
                    "HOSTNAME=localhost;PORT=50000;PROTOCOL=TCPIP;", $user, $password);
                    echo $user." Connected\n";
                    $xqry =
                <<<TXT
                    values( 
                    XMLSERIALIZE( XMLQUERY('
                    declare boundary-space strip;
                    declare namespace text0=
                    "urn:oasis:names:tc:opendocument:xmlns:text:1.0"; 
                    declare namespace office0=
                    "urn:oasis:names:tc:opendocument:xmlns:office:1.0"; 
                    
                    for \$t0 in db2-fn:xmlcolumn("DB2ADMIN.DOCUMENT.DOC")
                    /office0:document-content/office0:body/office0:text
                    let \$p := (for \$pp in \$t0/text0:p return <p>{\$pp/text()}</p>)
                    let \$h := (for \$hh in \$t0/text0:h[@text0:style-name=
                    "Heading_20_2"] 
                    return <hl>{\$hh/text()}</hl>)
                    return
                    
                    (\$h,\$p)')
                    as varchar(3000)))
                    TXT;
                    
                    echo "\n";
                    $result=$db->query( $xqry );
                    
                    $arr = $result->fetch();
                    echo $arr[1];
                ?>

要运行该代码,输入:

php.exe msrepurpose.php

现在您也许会问,为什么不直接将它保存为 HTML 呢?XML 的生成会危害原始文档的完整性,并且会丢失 MS Office 特性。然而,文档的确小了很多,而且仍然可以用 XQuery 对它进行再利用,就像对待 Word 2007 文件格式一样。随着文档变得越来越大、越来越多(例如在大型会议中),您希望将这个逻辑应用到储存库中每个文档的每个部分。于是 XQuery 的威力就表现出来了!和 SQL 一样,XQuery 使您通过一个查询处理一组文档。实际上,如果您愿意,也可以使用 SQL 查询得到同样的结果,因为在 DB2 中这两种语言可以互换。

下面的清单显示了 odfrepurpose.php 或 msrepurpose.php 的结果:

清单 6. 输出
db2admin Connected
<h1>Introduction to Web 2.0</h1><p>This is a document
 that will impress upon ...</p><h1>Abstract</h1><p>The nature of the industry is a
gain turning to the browser ...</p>

结束语

本文讨论的技巧在内容管理和文档管理解决方案中很有用。希望您已经发现,通过 IBM DB2 pureXML 特性使用和再利用 OpenOffice 和 MS Office 2007 文档十分容易。实际上这个过程不需要很多代码,这一点有助于取得好的性能。之后,考虑索引这些 XML 文档,以进一步利用 pureXML 混合存储特性的优点。

欲更深入地学习 XQuery,可以使用 DB2 Developer Workbench 中的 XQuery 编辑器,或者浏览 DB2 9: pureXML Overview and Fast Start (IBM Redbooks)。请访问 pecl.php.net 上的 IBM_PDO 站点,了解关于 PDO 的更多信息。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management, XML, Open source
ArticleID=254719
ArticleTitle=使用 DB2 9 pureXML 管理 ODF 和 Microsoft Office 2007 文档
publish-date=09122007