首页 > 开发 > XML > 正文

DB2 VS2005.Net插件进行XML数据验证

2024-09-05 20:56:02
字体:
来源:转载
供稿:网友

  一个存储库,例如关系数据库,可以为授权用户安全地共享 xml 文档和 xml 模式提供一个环境。授权用户可以在任何时候、任何地方安全地访问重要的 xml 文档和 xml 模式。通过使用可包含一个或多个关系数据库系统的存储库系统,用户可以找到并检索最新版本的 xml 文档和 xml 模式文档。db2® 9 为 xml 提供了新的支持,对于这种新支持,.net 应用程序开发人员可以很快地上手。这是因为 db2 9 让程序员可以像对待关系数据那样查询、插入、更新和删除 xml 数据 —— 使用熟悉的 ado .net 语句和标准的查询语言。本文展示一些关于如何使用 .net 构建采用 db2 xml 技术的应用程序的详细示例。db2 xml 技术允许以 xml 原有的分层格式来存储、验证和查询 xml。

  db2 中的 xml 支持

  db2 9 为管理、存储和查询 xml 数据引入了一些新的特性和机制:

  •   xml 数据类型使 db2 可以以 xml 本身的分层格式来存储 xml 文档。
  •   xml 查询语言支持基于业界标准,并包括新的对 sql 的 xml 扩展(也称 sql/xml)。

  支持基于用户提供的模式验证 xml 数据,这使得应用程序开发人员和数据库管理员可以对 db2 中存储的 xml 数据实施数据完整性约束。本文中的例子使用 db2 visual studio 2005 add-in。

  本文中的代码示例引用了 carpool 表,该表记录旧金山和圣何塞两地关于合伙用车的信息。清单 1 展示了该表的定义。另外,还需确保数据库启用了 xml。

  环境设置

  注意:应确保 sample 数据库在创建时启用了 xml(见后面的定义)。

  本文需要使用 visual studio .net 2005 和 db2 9。这两个产品的安装很简单。建议先安装 visual studio .net,然后再安装 db2 9。请记住在安装 db2 时所输入的用户 id 和密码,因为在连接 db2 时要使用它们。

  在 db2 安装期间,应确保启用了 tcp/ip。如果在安装 db2 之后不确定 tcp/ip 是否被启用,可以执行以下步骤进行检查:

  从 windows start 菜单中,选择 programs > ibm db2 > db2(默认)[或者为 db2 实例名称] > command line tools > command window。

  在 db2 命令窗口中,应该可以看到命令提示符 c:/program files/ibm/sqllib/bin>(如果使用默认安装路径的话)。输入 db2set。在返回的结果中,应该可以看到这一行: db2comm=tcpip。

  如果还没有为 db2 启用 tcp/ip,那么可以输入以下命令来启用 tcp/ip:

  db2set db2comm=tcpip

  db2 update dbm cfg using svcename 50000

  db2stop

  db2start

  安装了 db2 之后,可以选择创建 db2 sample 数据库。如果选择这么做,那么应接受默认设置,但务必选择 xml and sql objects and data 选项。

  为了检查系统设置是否成功,启动 visual studio .net 2005。在 visual studio .net 中,选择 file > new > project。在 new project 对话框中,在左侧面板中应该可以看到 ibm projects。关闭该对话框。在 server explorer 中,连接到 db2 sample 数据库。确认在 server explorer 中可以看到 xml schema repository 树节点。如果没有看到,那么可能需要重新创建 sample 数据库,以启用 xml 特性。

  清单 1. carpool 表定义

  create table carpool (

  id integer not null,

  firstname varchar ( 256 ) ,

  lastname varchar ( 256 ) ,

  title varchar ( 15 ) ,

  phone varchar ( 20 ) ,

  carpoolinfo xml ,

  constraint carpool_pk primary key (id))

  这里有两个 xml 模式,carpoolinfo.xsd 和 usaddresstype.xsd,其中 carpoolinfo.xsd 引用了 usaddresstype。

  清单 2. 用于验证 carpool 表中的 xml 文档的 xml 模式(carpoolinfo.xsd)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetnamespace="http://tempuri.org/xmlschema.xsd"
elementformdefault="qualified" xmlns="http://tempuri.org/xmlschema.xsd"
xmlns:mstns="http://tempuri.org/xmlschema.xsd"
xmlns:xs="http://www.w3.org/2001/xmlschema">
  <xs:include id="usaddress.xsd" schemalocation="usaddress.xsd" />
  <xs:element name="carpoolinfo">
    <xs:complextype>
      <xs:sequence>
        <xs:element name="starttime" type="xs:string" />
        <xs:element name="address" type="usaddress" />
      </xs:sequence>
    </xs:complextype>
  </xs:element>
</xs:schema>

  清单 3. carpoolinfo 依赖的 xml 模式(usaddress.xsd)

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetnamespace="http://tempuri.org/xmlschema.xsd"
elementformdefault="qualified" xmlns="http://tempuri.org/xmlschema.xsd"
xmlns:mstns="http://tempuri.org/xmlschema.xsd"
xmlns:xs="http://www.w3.org/2001/xmlschema">
  <xs:complextype name="usaddress">
    <xs:sequence>
      <xs:element name="add1" type="xs:string">
      </xs:element>
      <xs:element name="add2" type="xs:string">
      </xs:element>
      <xs:element name="city" type="xs:string">
      </xs:element>
      <xs:element name="state" type="xs:string">
      </xs:element>
      <xs:element name="zip" type="xs:string">
      </xs:element>
    </xs:sequence>
  </xs:complextype>
</xs:schema>

  carpool 表既包含基于 sql 数据类型的列,又包含一个基于新的 db2 xml 数据类型的列。后一个列,即 carpoolinfo,存储包括合伙用车者的地址和开始时间等信息的 xml 文档。图 1 展示了示例 carpoolnfo xml 文档。

  图 1. 存储在 carpool 表中的示例 xml 文档

  示例 xml 文档

  现在来看看如何插入、更新和验证 carpoolinfo 列中的 xml 文档。清单 2 展示了一个 xml 模式,在将一个 xml 文档插入 carpoolinfo 列之前,需要使用这个 xml 模式对该 xml 文档进行验证。

  为了编译和运行 .net 应用程序,需要创建一个新的 visual studio .net 项目。如果之前没有使用过 visual studio .net,那么可以看看下面关于如何完成这些任务的概述:

  1.   启动 visual studio 2005。
  2.   创建一个新项目。选择 file > new > project。选择 visual c# > windows application。
  3.   创建对 db2 .net 数据提供程序 ibm.data.db2 的引用。在 visual studio .net 项目管理器中,右键单击 references 节点,选择 add reference。选择 browse 选项卡,找到 ibm.data.db2.dll,该文件位于 db2 安装目录中,路径为 /sqllib/bin/netf20/ibm.data.db2.dll。

|||

  连接数据库

 

  首先需要建立到目标数据库的一个连接。清单 4 是用于建立 db2 数据库连接的一个方法的片段。

  清单 4. 建立 db2 数据库连接

  private db2connection m_conn = null;

  m_conn = new db2connection("database=sample");

  m_conn.open();

  注册 xml 模式

  db2 9 允许用户注册 xml 模式,并在插入输入文档之前,根据这些模式对输入文档进行验证。xml 模式是 world wide web consortium(w3c)业界标准的一部分。用户可以通过 xml 模式指定 xml 文档应遵从的结构,例如可接受的 xml 元素的顺序和数据类型,以及特定 xml 名称空间的使用。 db2 visual studio 2005 add-in 工具提供了一种使用简单的注册设计器来注册 xml 模式的简单方法,不过本文将展示如何使用 .net 代码注册 xml 模式。一旦在 db2 xml 模式库中注册了一个 xml 模式,便可以用该模式来验证 xml 文档。清单 5 展示了使用 .net 代码注册 xml 模式的一种方法。

  清单 5. 注册 xml 模式

  //we have two xsds, carpoolinfo.xsd and usaddress.xsd,

  //where carpoolinfo.xsd is dependent on usaddress.xsd.

  //this xml schema is identified as schema.xsdname.

  string[] xsdfiles = new string[2]

  {

  "carpoolinfo.xsd",

  "usaddress.xsd"

  };

  string[] schemalocs = new string[2]

  {

  "http://tempuri.org/carpoolinfo.xsd",

  "usaddress.xsd"

  };

  // register xml schema using db2 .net provider connection’s

  // registerxmlschema api

  m_conn.registerxmlschema(schema,xsdname,

  schemalocs,

  xsdfiles,

  null,

  null,

  false);

|||

  插入和验证 xml 数据

 

  至此,已经建立了 db2 连接并注册了 xml 模式,现在可以编写 sql insert 或 update 语句,以便将新的 xml 数据插入到包含 xml 列的表中,并在插入 xml 数据之前,让 db2 验证 xml 数据。db2 可以存储最大为 2gb 的格式良好的任何 xml 文档。清单 6 展示了将一行插入到 carpool 表中的一种方法。在这个例子中,插入到 carpoolinfo 列的 xml 文档是从字符串读取的。

  清单 6. 插入和更新 xml 数据的方法

  // update the database based on the user's action in the datagrid.

  // performs insert, update and delete.

  private void update()

  {

  mydatasourcedt = carpoolinfo.datasource as datatable;

  dtchanges = mydatasourcedt.getchanges();

  if (dtchanges == null)

  return;

  // need to generate insert/update/delete commands to //validate against

  // carpoolinfo.xsd

  db2command insert = new db2command

  ("insert into carpool" +

  "(firstname,lastname,title,phone,carpoolinfo)" +

  " values(?,?,?,?," +

  "xmlvalidate(xmlparse (document cast" +

  " ( ? as clob) preserve whitespace )" +

  "according to xmlschema id " + schema + ".carpoolinfo ))");

  db2command update = new db2command

  ("update carpool set firstname=?,lastname=?,title=?,phone=?," +

  "carpoolinfo=xmlvalidate(xmlparse (document cast " +

  "( ? as clob) preserve whitespace ) " +

  "according to xmlschema id " + schema + ".carpoolinfo ) where id=?");

  db2command delete = new db2command

  ("delete from carpool where id=?");

  //add the parameters and bind them to the datatable's //corresponding columns.

  db2parameter fn1 = new db2parameter("fn1", db2type.varchar);

  db2parameter fn2 = new db2parameter("fn2", db2type.varchar);

  fn1.sourcecolumn = "firstname";

  fn2.sourcecolumn = "firstname";

  insert.parameters.add(fn1);

  update.parameters.add(fn2);

  db2parameter ln1 = new db2parameter("ln1", db2type.varchar);

  db2parameter ln2 = new db2parameter("ln2", db2type.varchar);

  ln1.sourcecolumn = "lastname";

  ln2.sourcecolumn = "lastname";

  insert.parameters.add(ln1);

  update.parameters.add(ln2);

  db2parameter tl1 = new db2parameter("tl1", db2type.varchar);

  db2parameter tl2 = new db2parameter("tl2", db2type.varchar);

  tl1.sourcecolumn = "title";

  tl2.sourcecolumn = "title";

  insert.parameters.add(tl1);

  update.parameters.add(tl2);

  db2parameter ph1 = new db2parameter("ph1", db2type.varchar);

  db2parameter ph2 = new db2parameter("ph2", db2type.varchar);

  ph1.sourcecolumn = "phone";

  ph2.sourcecolumn = "phone";

  insert.parameters.add(ph1);

  update.parameters.add(ph2);

  db2parameter info1 = new db2parameter("info1", db2type.clob);

  db2parameter info2 = new db2parameter("info2", db2type.clob);

  info1.sourcecolumn = "carpoolinfo";

  info2.sourcecolumn = "carpoolinfo";

  insert.parameters.add(info1);

  update.parameters.add(info2);

  db2parameter i1 = new db2parameter("i1", db2type.integer);

  i1.sourcecolumn = "id";

  update.parameters.add(i1);

  db2parameter i2 = new db2parameter("i2", db2type.integer);

  i2.sourcecolumn = "id";

  delete.parameters.add(i2);

  da.insertcommand = insert;

  da.updatecommand = update;

  da.deletecommand = delete;

  // perform the update.

  da.update(dtchanges);

  mydatasourcedt.acceptchanges();

  // refill the dataset, refresh the datagridview.

  ds.clear();

  da.fill(ds, xsdname);

  }

  现在来看看这段代码。在建立数据库连接之后,该方法创建三个 db2command;一个用于插入,一个用于更新,还有一个用于删除。插入和更新命令包含 4 个用于常规列值的参数占位符,而第 5 个参数占位符则用于 xml 列,该方法还使用 db2 xmlvalidate 函数,并将 carpoolinfo xml 模式传递给它以便进行验证。

|||

  查询 xml 数据

 

  至此,已经将数据存储在 carpoolinfo 表中,现在可以查询这个表。db2 允许编写不同类型的查询来提取关系数据和 xml 数据。例如可以编写一个简单的查询来检索整个 xml 文档,或者编写一个基于 xml 和关系查询谓词检索 xml 文档某些部分的查询。本文演示一个这样的查询:

  1.   基于 xml 谓词过滤数据
  2.   检索符合条件的 xml 文档的某些部分,以及存储在传统 sql 列中的数据

  本文使用 db2 的 xmlexists() 函数。本文中的示例应用程序使用 xmlexists() 来演示一个常见的编程任务:检索 xml 文档的某些部分。清单 7 中显示的例子返回居住在旧金山或圣何塞的合伙用车者的合伙用车信息。这个例子同时投影和限制传统的 sql 数据和 xml 数据。

  清单 7. 查询 xml 数据

  // populate the datagrid.

  // if "all" is selected, all data from the table will be displayed.

  // if a city's name is selected, only rows whose carpoolinfo contain

  // cityname will be displayed.

  public void populate(string cityname)

  {

  if ( cityname.equals("all"))

  {

  carpoolinfo.datasource = ds.tables[xsdname];

  }

  else

  {

  xq = "select * from carpool where " +

  "xmlexists('declare namespace

  def=/"http://tempuri.org/xmlschema.xsd/";" +

  "$c/def:carpoolinfo/def:address[def:city=" + "/"" + cityname +

  "/"]' passing carpool.carpoolinfo as /"c/")" +

  "order by id";

  db2dataadapter da1 = new db2dataadapter(xq, m_conn);

  dataset ds1 = new dataset();

  da1.fill(ds1, xsdname);

  carpoolinfo.datasource = ds1.tables[xsdname];

  }

  }

  where 子句使用 db2 的 xmlexists() 函数限制查询所返回的数据。它规定,返回的 xml 文档只包括在 carpoolinfo 的 city 为某个值(san francisco 或 san jose)的行中的那些 xml 文档。在这个示例查询中,xmlexists() 指示 db2 判断一个给定的 xml 文档是否包含一个包括指定城市的 carpool 地址。passing 子句指定 xml 文档所在的位置(在 carpoolinfo 列中)。

  结束语

  ibm db2 使程序员可以用熟悉的 sql 语句更新和删除 xml 数据。为了更新和删除存储在 db2 中的 xml 数据,可以使用 sql update 和 delete 语句。这些语句可以包括 sql/xml 函数,这种函数可根据 xml 列中存储的 xml 元素的值来限制目标行和列。例如,可以删除包含居住在特定城市的合伙用车者的相关信息的行,或者只更新合伙用车的开始时间在某个给定时间段内的合伙用车者的 xml(和非 xml 数据)。由于在 update 和 delete 语句中使用 sql/xml 函数的语法与在 select 语句中使用这些函数的语法相同,因此不再给出完整的代码示例。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表