如何将XML文件中的数据传送并保存在关系数据库中

时间:2006-12-09 08:33:43  来源:  作者:

在AJAX、网络服务与纯XML之间存在大量的数据传输。XML确实使数据传输更加方便。虽然这相当不错,不过它完全忽略了一个事实,即最终数据必须存储在某个地方,最可能是在一个关系数据库中。这带来了一个问题:如何将XML文件中的信息存储到关系数据库中呢?4M3第一天空网络

理想情况下,这种程序很明显;但事实并非如此。哎!如果我长得像布拉德皮特并拥有比尔盖茨的支票薄就好了。我使它接近完美,我做出如下选择:4M3第一天空网络

  • 整容手术
  • 释放我的机器人杀手军队

哈,错误的选择。再试一次。4M3第一天空网络

  • 每次插入使用一个单独SQL语句的单纯循环方法。
  • 建立许多可以立即执行的界定SQL语句的单纯循环方法。
  • 应用XSL建立SQL的科学方法。

我会选择哪个方法,介意猜一猜吗?4M3第一天空网络

对,我肯定会选择第三个方法。所以,让我们了解一下我们将要处理的XML,如列表A所示。没有华而不实,只是必要的概念证据。4M3第一天空网络

列表A——输入XML文件4M3第一天空网络

<?xml version="1.0" ?>4M3第一天空网络

<!-- Edited with the Butterfly XML Editor (http://www.butterflyxml.org) -->4M3第一天空网络

<root>4M3第一天空网络

<row>4M3第一天空网络

<state_id>PA</state_id>4M3第一天空网络

<state_name>Pennsylvania</state_name>4M3第一天空网络

</row>4M3第一天空网络

<row>4M3第一天空网络

<state_id>NJ</state_id>4M3第一天空网络

<state_name>New Jersey</state_name>4M3第一天空网络

</row>4M3第一天空网络

</root>4M3第一天空网络

下面,我们查看一下我们建立插入的表格,如A4M3第一天空网络

表A——Tarqet4M3第一天空网络

state_id4M3第一天空网络

VARCHAR2(2)4M3第一天空网络

state_name4M3第一天空网络

VARCHAR2(50)4M3第一天空网络

利用这些信息,我们可以采取两种可能的行动。第一种是建立一个XSL式样表,它模仿第一个方法:“每次插入使用一个单独SQL语句的单纯循环方法”。这个方法具有速度与通用性的优势,毕竟XSL是一个世界通用的标准。4M3第一天空网络

列表B所示,这个任务所需的XSL与多数其它XSL类似,只有少数几点不同,下面我来分别指出这些差异:首先,专门针对介质类型的xsl:output元素。在这个式样表中,介质类型设定为text/sql,而非默认的text/xml或常见的text/html。另外一个巨大的差异就是其中包含了in.xslsqlApostrophe.xsl,它们用来决定那些元素中与数字相对的文本或日期,并用双引号代替单引号来防止SQL问题。另外,还有用来建立输出的xsl:textxsl:value-of元素。4M3第一天空网络

列表B——XSL式样表4M3第一天空网络

<?xml version="1.0"?>4M3第一天空网络

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">4M3第一天空网络

<xsl:param name="table"/>4M3第一天空网络

<xsl:param name="textColumns"/>4M3第一天空网络

<xsl:param name="dateColumns"/>4M3第一天空网络

<xsl:includehref="in.xsl"/>4M3第一天空网络

<xsl:includehref="sqlApostrophe.xsl"/>4M3第一天空网络

<!--4M3第一天空网络

Stylesheet:sample.xsl4M3第一天空网络

Creation Date:October 25, 20064M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this XSL style sheet is to generate multiple SQL insert statements.4M3第一天空网络

Template:match="/"4M3第一天空网络

Creation Date:October 25, 20064M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to create the outer sql element and invoke the template for the individual INSERT statements.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="/">4M3第一天空网络

<xsl:element name="sql">4M3第一天空网络

<xsl:apply-templates select="//row"/>4M3第一天空网络

</xsl:element>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="row"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to control the creation of the INSERT statements.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="row">4M3第一天空网络

<xsl:element name="statement">4M3第一天空网络

<xsl:value-of select="concat('INSERT INTO ',$table,' (')"/>4M3第一天空网络

<xsl:apply-templates select="*" mode="name"/>4M3第一天空网络

<xsl:text>) VALUES (</xsl:text>4M3第一天空网络

<xsl:apply-templates select="*" mode="value"/>4M3第一天空网络

<xsl:text>)</xsl:text>4M3第一天空网络

</xsl:element>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="*" mode="name"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to list the column names.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="*" mode="name">4M3第一天空网络

<xsl:if test="position() != 1">4M3第一天空网络

<xsl:text>, </xsl:text>4M3第一天空网络

</xsl:if>4M3第一天空网络

<xsl:value-of select="name(.)"/>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="*" mode="value"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to list the column values.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="*" mode="value">4M3第一天空网络

<xsl:variable name="text">4M3第一天空网络

<xsl:call-template name="in">4M3第一天空网络

<xsl:with-param name="list" select="$textColumns"/>4M3第一天空网络

<xsl:with-param name="value" select="name(.)"/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

</xsl:variable>4M3第一天空网络

<xsl:variable name="date">4M3第一天空网络

<xsl:call-template name="in">4M3第一天空网络

<xsl:with-param name="list" select="$dateColumns"/>4M3第一天空网络

<xsl:with-param name="value" select="name(.)"/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

</xsl:variable>4M3第一天空网络

<xsl:if test="position() != 1">4M3第一天空网络

<xsl:text>, </xsl:text>4M3第一天空网络

</xsl:if>4M3第一天空网络

<xsl:choose>4M3第一天空网络

<xsl:when test="$text = 'true'">4M3第一天空网络

<xsl:text>'</xsl:text>4M3第一天空网络

<xsl:call-template name="sqlApostrophe">4M3第一天空网络

<xsl:with-param name="string" select="."/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

<xsl:text>'</xsl:text>4M3第一天空网络

</xsl:when>4M3第一天空网络

<xsl:when test="$date = 'true'">4M3第一天空网络

<xsl:value-of select="."/>4M3第一天空网络

</xsl:when>4M3第一天空网络

<xsl:otherwise>4M3第一天空网络

<xsl:value-of select="."/>4M3第一天空网络

</xsl:otherwise>4M3第一天空网络

</xsl:choose>4M3第一天空网络

</xsl:template>4M3第一天空网络

</xsl:stylesheet>4M3第一天空网络

当然,这个方法仍然存在问题,我们必须遍历XML文件来逐个执行SQL语句,这是一件我最不喜欢的事情。但是,这个问题有别的解决方法:将单独的语句用逗号分隔开来,建立一个复合SQL语句。4M3第一天空网络

我不认为我懒惰,相反我认为自己有效率。毕竟这个方法比前一个方法更不易出错。因此只需稍稍做一些改变,主要是转移一些代码,我建立了如列表C所示的XSL式样表。4M3第一天空网络

列表C——高效XSL样式表4M3第一天空网络

<?xml version="1.0"?>4M3第一天空网络

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">4M3第一天空网络

<xsl:param name="table"/>4M3第一天空网络

<xsl:param name="textColumns"/>4M3第一天空网络

<xsl:param name="dateColumns"/>4M3第一天空网络

<xsl:includehref="in.xsl"/>4M3第一天空网络

<xsl:includehref="sqlApostrophe.xsl"/>4M3第一天空网络

<!--4M3第一天空网络

Stylesheet:sample.xsl4M3第一天空网络

Creation Date:October 25, 20064M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this XSL style sheet is to generate multiple SQL insert statements.4M3第一天空网络

Template:match="/"4M3第一天空网络

Creation Date:October 25, 20064M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to create the outer sql element and invoke the template for the individual INSERT statements.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="/">4M3第一天空网络

<xsl:element name="sql">4M3第一天空网络

<xsl:apply-templates select="//row"/>4M3第一天空网络

</xsl:element>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="row"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to control the creation of the INSERT statements.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="row">4M3第一天空网络

<xsl:value-of select="concat('INSERT INTO ',$table,' (')"/>4M3第一天空网络

<xsl:apply-templates select="*" mode="name"/>4M3第一天空网络

<xsl:text>) VALUES (</xsl:text>4M3第一天空网络

<xsl:apply-templates select="*" mode="value"/>4M3第一天空网络

<xsl:text>)</xsl:text>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="*" mode="name"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to list the column names.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="*" mode="name">4M3第一天空网络

<xsl:if test="position() != 1">4M3第一天空网络

<xsl:text>, </xsl:text>4M3第一天空网络

</xsl:if>4M3第一天空网络

<xsl:value-of select="name(.)"/>4M3第一天空网络

</xsl:template>4M3第一天空网络

<!--4M3第一天空网络

Template:match="*" mode="value"4M3第一天空网络

Programmer:Edmond Woychowsky4M3第一天空网络

Purpose:The purpose of this template is to list the column values.4M3第一天空网络

Update Date:Programmer:Description:4M3第一天空网络

-->4M3第一天空网络

<xsl:template match="*" mode="value">4M3第一天空网络

<xsl:variable name="text">4M3第一天空网络

<xsl:call-template name="in">4M3第一天空网络

<xsl:with-param name="list" select="$textColumns"/>4M3第一天空网络

<xsl:with-param name="value" select="name(.)"/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

</xsl:variable>4M3第一天空网络

<xsl:variable name="date">4M3第一天空网络

<xsl:call-template name="in">4M3第一天空网络

<xsl:with-param name="list" select="$dateColumns"/>4M3第一天空网络

<xsl:with-param name="value" select="name(.)"/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

</xsl:variable>4M3第一天空网络

<xsl:if test="position() != 1">4M3第一天空网络

<xsl:text>, </xsl:text>4M3第一天空网络

</xsl:if>4M3第一天空网络

<xsl:choose>4M3第一天空网络

<xsl:when test="$text = 'true'">4M3第一天空网络

<xsl:text>'</xsl:text>4M3第一天空网络

<xsl:call-template name="sqlApostrophe">4M3第一天空网络

<xsl:with-param name="string" select="."/>4M3第一天空网络

</xsl:call-template>4M3第一天空网络

<xsl:text>'</xsl:text>4M3第一天空网络

</xsl:when>4M3第一天空网络

<xsl:when test="$date = 'true'">4M3第一天空网络

<xsl:value-of select="."/>4M3第一天空网络

</xsl:when>4M3第一天空网络

<xsl:otherwise>4M3第一天空网络

<xsl:value-of select="."/>4M3第一天空网络

</xsl:otherwise>4M3第一天空网络

</xsl:choose>4M3第一天空网络

</xsl:template>4M3第一天空网络

</xsl:stylesheet>4M3第一天空网络

结论4M3第一天空网络

过去几年来,我一直在使用这种,或与它类似的方法,都取得了很好的效果。尽管从SQL角度看,它的执行速度比不上比更常见的建立SQL的字符串串联方法提供更好结果的存储过程。我还想指出的是,我说过我使用这个或与它类似的方法,基本只增加了commit和rollback语句来处理错误。不过,这些修改仅仅是个人尝试和个人偏执行为。4M3第一天空网络

文章评论

共有 位天空网友发表了评论 查看完整内容

特别推荐
  • 文字广告
  • 文字广告
  • 文字广告
  • 文字广告
站长黑板报

24小时热门信息