你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
ADO记录集向XML文档的转换
 

为什么

面对漫天飞舞的XML曾经迷惑,不就是一种带格式的文本文件吗,为什么会惹得众多软件巨头竞相追捧,以致成为网络时代的通用表达语言?仔细研究下来,XML的以下特点使之成为互联网上的新宠:

1.      通用性:自从其诞生的那天起,便立志成为电子商务时代的世界语,所以它采用了一种结构化的ASCII文本文件,任何系统都可以方便的与之沟通。

2.  开放:XMLW3C所制定的标准语法,并已获得软件工业的认可。

3.  可扩展:无固定不变的标记,可根据需求创建新标记。

4.  自我描述能力:DTDXML的每个部分做了声明与精确的格式定义。而SCHEMAXML文档元素的规则组合,它指定文本中所允许的元素,及其可能的组合。

正因为此,通过ADO取得的数据记录,保存为XML文档,有着广泛的应用价值,下面详细讨论之。

目标

现有一个ACCESS数据库PeiXun.mdb,一个kecheng数据表,其结构如下图所示:

我们将把其内容保存为如下格式的XML文档:

- <xml>

- <row>

  <id>3</id>

  <classid>1 </classid>

  <date>2003524</date>

<curriculum_name>MBA考前辅导第一期基础班</curriculum_name>

 </row>

  </xml>

正如我们所熟悉的用ASP操作数据库模式,先创建一个conn..asp文件,用于打开数据库,在后面的代码中都会用到:

<%

    on error resume next

    dim conn,connstr

    dim dbpath

    connstr="DBQ="+server.mappath("DataBase/peixun.mdb")+";DefaultDir=;DRIVER={Microsoft Access Driver (*.mdb)};"

   set conn=server.createobject("adodb.connection")

    conn.Open  connstr

%>

 

方案一

基本上,维护XML文档的技术有三种,第一种是使用DOM(Document Object Modal)接口,第二种是通过SAX(Simple API for XML),第三种是采用传统的字符串维护。

所谓DOM就是把整个XML文档加载到一个树状结构的节点中,然后再通过维护树状结构的方式来改变XML文档,使用DOM时,整个XML文档必须先加载到内存中。

实际上,很多家公司都实现了DOM,包括IBM,ApacheMicrosoft等,而Microsoft公司是把DOM的实现放在MSXML SDK内,而MS IE 也使用DOM 。下面我们就使用MSXML对象实现从ADO RecordSet XML文档的转化。

1. 取得ADO数据记录集

<!--#include file ="conn.asp"-->

<%

    Dim strsql

    Dim objRecordset

        Dim fileObj

    strsql=" select  id,class_id,date, curriculum_name  from kecheng "                 

    set objRecordset=conn.execute (strsql)                 

 %>

2. 创建XMLDOM对象

<%

Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")

    '创建根节点<xml>

    Set objRootNode = objXMLDOM.createElement("xml")

    objXMLDOM.documentElement = objRootNode

    createProcessingInstruction方法处理指令

objXMLDOM.appendChild(objXML.createProcessingInstruction("xml","version=""1.0"""))

%>

3. 循环把数据集中的每条记录写到DOM的节点中去:

<%

Do While NOT objRecordset.EOF

    '创建子元素 row

    Set objRowNode = objXMLDOM.createElement("row")

    '创建子元素 id

    Set objNode = objXMLDOM.createElement("id")

    objNode.text = _

         objRecordset.Fields.Item("id").Value

    'id 作为row 的子节点 添加到row

    objRowNode.appendChild(objNode)

    '创建 classid节点,并使之为row的子节点

Set objNode = objXMLDOM.createElement("classid")

    objNode.text = _

         objRecordset.Fields.Item("classid").Value

    objRowNode.appendChild(objNode)

    '创建 date节点,并使之为row的子节点

Set objNode = objXMLDOM.createElement("date")

    objNode.text = _

         objRecordset.Fields.Item("date").Value

    objRowNode.appendChild(objNode)

    '创建 curriculum_name节点,并使之为row的子节点

Set objNode = objXMLDOM.createElement("curriculum_name")

    objNode.text = _

         objRecordset.Fields.Item("curriculum_name").Value

    objRowNode.appendChild(objNode)

    'row 作为xml的子节点添加

objRootNode.appendChild(objRowNode)

    '移到下一条记录

objRecordset.MoveNext

Loop

%>

4. 调用save方法 保存XML文件

<%

objXMLDOM.save(server.MapPath("kecheng.xml"))

%>

5. 释放资源

<%

Set objNode = Nothing

Set objRowNode = Nothing

Set objRootNode = Nothing

Set objRecordset = Nothing

%>

您肯定发现了,第3步写得好罗嗦啊,完全可以用RecordSetFields属性,循环取出所有的字段,如下所示:

<%

Do While NOT objRecordset.EOF

        '创建子元素 row

        Set objRowNode = objXMLDOM.createElement("row")

        For Each varItem In objRecordset.Fields

           Set objNode = objXMLDOM.createElement(varItem.name)

           objNode.text =varItem.value

           objRowNode.appendChild(objNode)

        Next

       ' row 作为xml的子节点添加

        objRootNode.appendChild(objRowNode)

        objRecordset.MoveNext

Loop

%>

这样写即简洁又通用,实际上写程序的过程就是不断精益求精的过程啊。

方案二

我们把记录集和XML格式串放到字符串中,生成目标中所示的格式,然后把字符串写到一个文本文件中。

1. 同方案一中第一步取得ADO数据记录集。

2. 定义XML格式初始化字符串:

<%

Dim strXML

strXML = "<?XML version="&""""&"1.0"&""""&" encoding="&""""&"gb2312"&""""&"?>"

strXML = strXML & "<xml>"

%>

注意我们在这里把XML文档的encoding属性定义为gb23312,以防止中文字符在XML解析器中(如IE)解析时出现错误。

3. 循环把数据集中的每条记录附加到所定义的字符串中:

<%

objRecordset.MoveFirst

    Do While NOT objRecordset.EOF

        For Each varItem In objRecordset.Fields

           strXML = strXML _

                &"<"_

                &varItem.name_

                &">"_

                &varItem.value_

                &"</"_

&varItem.name_

&">"

        Next

   Loop

     strXML = strXML & "</xml>"

Set objRecordset = Nothing

%>

4. 把字符串保存到文件中去:

   <%

 Dim FileObject,OutFile

调用系统文件对象

SET FileObject=Server.CreateObject("Scripting.FileSystemObject")

   创建文本文件

Set OutFile=FileObject.CreateTextFile(server.MapPath("kc1.xml"),TRUE,FALSE)         

    把字符串写到文件中去。

    OutFile.WriteLine(strXML)

    OutFile.Close

    Set OutFile=Nothing

Set FileObject=Nothing

%>

方案三

实际上ADORecordSet对象中有一个Save方法,可以直接把数据保存为XML格式。下面我们看看是如何使用的:

1.  同方案一中第一步取得ADO数据记录集。

   2.创建DOMDocument对象,并调用RecordSetSave方法,把数据保存到DOMDocument中去。Save方法在ADODB RecordSet 的对象中是这样声明的:

Sub Save([FileName As String], _

          [PersistFormat As PersistFormatEnum = adPersistADTG])

Save 方法的两个参数都是可选的,但若是第一次调用,必须指定文件名Filename

Save 不关闭 Recordset FileName,从而可以继续使用 Recordset 并保存最新的更改。在 Recordset 关闭之前 FileName 将保持打开,在这段时间其它应用程序可以读取但不能写入 FileName

PersistFormatEnum 值,指定保存 Recordset 所使用的格式。可以是如下的某个常量

AdPersistADTG

(默认)使用专用的“Advanced Data Tablegram”格式保存。

AdPersistXML

使用 XML 格式保存。

以上是MSDN中对该方法的描述,据此,可以利用SaveRecordSet保存为XML文件:

objRecordset.save server.MapPath("ceshi.xml"), adPersistXML

需要注意的是,Filename并不一定是磁盘文件,也可以是内存流对象,比如DOMDocument

下面把第二步中的代码列于此:

<%

Const adPersistXML = 1

Dim objXMLDOM

Set objXMLDOM = Server.CreateObject("MSXML2.DOMDocument.3.0")

objRecordset.save objXMLDOM, adPersistXML

%>

这样,数据记录就保存到了objXMLDOM对象中了,为什么不直接保存成XML文件呢?这是因为通过该方法保存成的XML文件附加了一些我们目标中不需要的信息:

这些信息是XML文档的架构(Schema)信息。它包含了RecordSet中记录的描述,其中<s:Schema> 定义了各字段的名称,类型及其它一些属性; <rs:data> RecordSet中的所有数据记录 <z:row>则具体到每一条记录的信息。我们的任务下一步就是利用XSLT把该文档转化为目标中XML文档的格式。

3.利用XSLTXML文档进行转换。那么什么是XSLT呢?它是Extensible Stylesheet Language Transformations 的缩写,是一种专为XML设计的样式表语言,负责将XML源代码转化为另一种格式。XSLT转换必须由特定的软件来担任,这样的软件称为XSL处理器。XSL处理器在工作之前,得先借助XML解析器替它把XSLT样式表和待转换的XML文档中的节点和属性分离出来,分离的结果我们程之为源树,指的是转换前的XML结构。然后,XSL处理器根据XSL中的命令对XML文档的源树进行操作,得到转换的成品,我们称之为结果树。下图就是利用XSLTXML进行转换的原理图。

.

下面我们就编写XSLT文件 RecordsetCleaner.xsl

<%

<?xml version="1.0"?>

<!-- RecordsetCleaner.xsl -->

<xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"

    xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"

    xmlns:rs="urn:schemas-microsoft-com:rowset"

    xmlns:z="#RowsetSchema">

<xsl:output omit-xml-declaration="yes"/>

<xsl:template match="/">

    <xsl:element name="xml">

        <xsl:for-each select="/xml/rs:data/z:row">

            <xsl:element name="row">

                <xsl:for-each select="@*">

                    <xsl:element name="{name()}">

                        <xsl:value-of select="."/>

                    </xsl:element>

                </xsl:for-each>

            </xsl:element>

        </xsl:for-each>

    </xsl:element>

</xsl:template>

</xsl:stylesheet>

%>

4.调用XSLT转换。现在XSLT文件已经准备好了,开始让它与XML文档发生作用吧。记住,我们在第二步的时候已经把RecordSet保存在了objXMLDOM中。

<%

Dim strCleanXML, objXMLDOM_XSLT

Set objXMLDOM_XSLT = CreateObject("MSXML2.DOMDocument.3.0")

objXMLDOM_XSLT.load(Server.MapPath("RecordsetCleaner.xsl"))

strCleanXML = objXMLDOM.transformNode(objXMLDOM_XSLT)

%>

现在,strCleanXML字符串中就保存着我们目标中所要求的XML文档。下一步就是要把它保存在磁盘文件中去。

5.保存为文件。

<%

objXMLDOM.loadXML(strCleanXML)

objXMLDOM.save(server.MapPath("test1.xml"))

Set objXMLDOM = Nothing

Set objXMLDOM_XSLT = Nothing

Set objRecordset = Nothing

%>

在这里,我们复用了objXMLDOM对象,通过调用loadXML方法,其内容已经变为已经减肥过的XML文档内容了。

遗留问题

当数据集中的数据包含 <,>XML保留字符时,转换将会失败,我们在上面的讨论中并没有注意这个问题。在实际开发中,要首先对这些字符进行过滤,然后才能进行转换。

 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089