独上高楼网站
  •    你所在位置:首页 VS.netXMLXML经验〉支持 XML Web 服务的 Office 文档 (Extreme XML)
  • 支持 XML Web 服务的 Office 文档 (Extreme XML)
  • 作者:佚名  文章来源:http://msdn2.microsoft.com/zh-cn/default.aspx  发布日期:2007-07-07  浏览次数:577
  • 打印这篇文章
  • 本页内容

    如何完成所有这些工作?

    目录 Web 服务

    Send 按钮

    试一试

    后续步骤

    下载 Xml03192001.exe

    您是否准备就绪,将 Microsoft Office XP .NET Web 服务进行结合?在 B2B 电子商务的网络世界中,为什么不将业务处理工作流集成到人们从其桌面所做的一切事情中,从而向最终用户提供 Web 服务的强大功能?我在谈论什么?哦,我在谈论一个看起来有些象图 1 所示的 Excel 电子表格。

    1. 支持 Web 服务的 Excel 电子表格

    这可不是一个普通的电子表格。它使用 UDDI 来查找公司的地址,并使用目录 Web 服务来查找产品信息。当您单击 Send 按钮时,它还会对 XML 电子表格格式进行 XML 转换,生成一个 RosettaNet PIP 3 A4 采购定单申请格式。

    键入要购买其商品的公司名称后,单击 Find 按钮,电子表格下的某个 VBA 代码将调用 UDDI 并填写地址部分其余的内容。例如,键入 Microsoft,单击 Find,您将在 Purchase From 字段中看到下面的内容:

    2. Purchase From 字段

    键入数量(例如 23),并在 description 字段中键入 Pear,然后按 Tab 键,某个 VBA 代码将查询 SOAP 目录 Web 服务,看是否有匹配的产品,并填写详细信息。在本例中,我已将目录 Web 服务连接到 Northwind 数据库,因此它将返回以下信息:

    3. 电子表格采购定单部分的详细情况

    在本例中,还填写了说明并将其转化为一个指向详细介绍此产品的 HTML 页面的链接。

    如果找到多个产品但没有一项完全满足您键入的条件,则将提供一个选项下拉列表。例如,如果您键入 tofu,您将看到下列选项:

    4. 未找到完全匹配项时所提供的多个选项的示例

    如果您选择其中一项,则将提供此项的具体详细信息。

    完成后,单击 Send 按钮,即生成 RosettaNet PIP 3 A4 XML 采购定单格式,并发送该定单。

    如何完成所有这些工作?

    通过访问 Tools 菜单,选择 Macro,然后选择 Visual Basic Editor,您可以浏览 VBA 代码。ThisWorkbook 下的某些代码会对电子表格中的变更做出响应,特别是当您删除说明时,Workbook_SheetChange 事件将清除一个行项目;当您将 Description 字段移入 SKU 字段时,Workbook_SheetSelectionChange 事件将调用 FindProduct()。如果 FindProduct 返回 XMLNode,将从该节点提取出相关的字段,以填充行项目的其余详细信息。

    有关 UDDI find_business 调用的工作方式,可查阅我以前的一篇文章 UDDI:An XML Web Service。如果找到一家公司,则在 UDDI 响应的 /businessInfo/contacts/contact/address/ 部分中找到的 addressLines 将用来填充 Purchase From 地址块。

    返回页首

    目录 Web 服务

    Catalogs 模块中的 FindProduct 函数将使用包含搜索项的 URL 参数来调用目录服务 URL。它会得到一个 SOAP 响应并首先检查是否与 /Envelope/Body/Fault 匹配,如果返回的不是 Fault,它将继续打开 CatalogQueryResult> 检查,以查看返回项目中的 ProductName 属性是否与给定项相匹配。它还会在可视区域以外的页面创建下拉选项列表。您可以在 Data 菜单中选择 Validation 来查看下拉列表的工作方式。

    目录 Web 服务十分简单。.aspx 入口点将创建一个 CatalogSearch 对象(该对象在 search.cs 中定义并调用 Execute),并按下列方式传递 HttpResponse 输出流:

    %@Language="C#" src="search.cs"  Debug="true" %>

    %

       Response.ContentType = "text/xml";

       string term = Request.QueryString["term"];

       if (term != null) {

          CatalogSearch s = new CatalogSearch(term);

          s.Execute(output);

       } else {

          Response.Write("Empty/>");

       }

    %>

                             

    真正的乐趣将从 Execute 方法开始。这是一个包装在 XmlTextWriter 中的、十分简单的 SQL 托管提供程序代码,它能够从 SQL SELECT 语句返回特定的字段。因此,它基本上是一个通过 DataReader XmlTextWriter 写入以下内容的 while 循环:

    public void Execute(TextWriter stm)

    {     

       XmlTextWriter xw = new XmlTextWriter(stm);

       xw.WriteStartElement("Envelope", "http://schemas..../envelope/");

       xw.WriteStartElement("Body", "http://schemas..../envelope/");

       try {

          String const = "server=localhost;uid=sa;pwd=;database=northwind";

          SQLConnection con = new SQLConnection(constr);

          con.Open();

          IDataReader reader;

          String query = "SELECT ProductName,UnitPrice,QuantityPerUnit," +

                "SupplierID,ProductID FROM Products WHERE " +

                "ProductName LIKE '%" + term + "%'";

          SQLCommand cmd = new SQLCommand(query, con);

          cmd.Execute(out reader);

          string funNamespace = "urn:schemas-b2b-fun:catalogs";

          xw.WriteStartElement("CatalogQueryResult", funNamespace);

          while (reader.Read())

          {

              xw.WriteStartElement("item");

              xw.WriteAttribute("ProductName", reader.GetString(0));

              xw.WriteAttrDecimal("UnitPrice", reader.GetDecimal(1));

              xw.WriteAttribute("UnitOfMeasure", reader.GetString(2));

              xw.WriteAttribute("SKU", "S"+reader.GetInt32(3)+

    "-P"+reader.GetInt32(4));

              xw.WriteEndElement();

          }

          xw.WriteEndElement();

          con.Close();

       } catch (Exception e) {

          xw.WriteStartElement("Fault");

              xw.WriteElementString("faultcode","500");

              xw.WriteElementString("faultstring",e.ToString());

          xw.WriteEndElement();

       }

       xw.WriteEndElement();

       xw.WriteEndElement();

       xw.Close();

    }

                             

    URL http://localhost/catalog/search.aspx?term=tofu 将返回以下结果:

    Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">

    Body>

      CatalogQueryResult xmlns="urn:schemas-b2b-fun:catalogs">

        item ProductName="Tofu" UnitPrice="23.25"

     UnitOfMeasure="40 - 100 g pkgs." SKU="S6-P14"/>

        item ProductName="Longlife Tofu" UnitPrice="10"

     UnitOfMeasure="5 kg pkg." SKU="S4-P74"/>

      /CatalogQueryResult>

    /Body>

    /Envelope>

                             

    这可能是使用 .NET 框架从 SQL Server 获得 XML 的最高效的方式。粗略计算,在我的 Dell PowerEdge 2400 上每秒可获得其中的 80 90 个这样的 XML

    返回页首

    Send 按钮

    SendOrder() 函数可以从电子表格中选定范围的单元格的 XML 表示形式加载 XML 文档。通过下列神奇的 VBA 代码行便可以实现这一切:

    With ActiveSheet

      Set sourcexml = New MSXML2.DOMDocument

      sourcexml.loadXML .Range("B1:N34").value(xlRangeValueXMLSpreadsheet)

    End With        

                             

    这将返回一个巨大的 XML 块,完整说明有关电子表格中选定范围的单元格的全部信息。下面是 XML 块的代码片断:

    Workbook>

        Worksheet>

             Table>

                 Row>